---
title: "Rewrites and proxies"
description: "Use rewrite rules to fetch a location behind the scenes while the URL in the visitor's address bar remains the same. Proxy to another service or site."
---

> For the complete documentation index for AI agents, see [llms.txt](https://docs.netlify.com/llms.txt). Markdown versions of any documentation page are available by appending `.md` to its docs.netlify.com URL.

When you assign an [HTTP status code](/manage/routing/redirects/redirect-options#http-status-codes) of `200` to a redirect rule, it becomes a **rewrite**. This means that the URL in the visitor's address bar remains the same, while Netlify's servers fetch the new location behind the scenes.

This can be useful for single page apps, proxying to other services, proxying to other Netlify sites (internal rewrites), or transitioning for legacy content.

Except where noted, the examples on this page use the [`_redirects` file syntax](/manage/routing/redirects/overview#syntax-for-the-_redirects-file), but all of these options are available in the [Netlify configuration file syntax](/manage/routing/redirects/overview#syntax-for-the-netlify-configuration-file) as well.

## Limitations

Rewrites can be very powerful, but there are a few things they cannot do:

- For security reasons, rewrites between Netlify sites belonging to different teams are not allowed.
- Infinitely looping rules, where the "from" and "to" resolve to the same location, are incorrect and will be ignored.
- By default, we limit internal rewrites to one "hop" - you cannot proxy from Netlify SiteA to Netlify SiteB to Netlify SiteC in a single request. This limitation may be amended for customers on a case-by-case basis. [Contact support](https://www.netlify.com/support) for more information.
- Proxy rewrite requests will time out after 26 seconds. If you are proxying to a longer-running process, we recommend making an asynchronous request rather than waiting for a response.
- Rewrites can cause pages that use assets specified through relative paths to load incorrectly. To make sure your site's proxied content is displayed as expected, use absolute paths for your assets or a [`<base>`](https://www.w3schools.com/tags/tag_base.asp) tag.
- Paths handled by [proxies](/manage/routing/redirects/rewrites-proxies) or [functions](/build/functions/overview) may not redirect from HTTP to HTTPS URLs as expected. If you're working with proxies or functions, we recommend only publishing HTTPS URLs for your visitors to use.
- While rewrites within the same password-protected site are supported, rewrites to separate password protected sites are not allowed.

## History `pushState` and single-page apps

If you're developing a single page app and want the history `pushState` method to work so you get clean URLs, you'll want to add the following rewrite rule. If you have other redirect or rewrite rules, this is typically the last rule listed.

### Tabs Component:

<TabItem label="_redirects file">
``` 
/*  /index.html  200
```
</TabItem>

<TabItem label="netlify.toml file">
``` toml
[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200
```
</TabItem>

This will effectively serve the `index.html` instead of giving a `404` no matter what URL the browser requests.

## Shadowing

By default, you can't shadow a URL that actually exists within the site. This applies to rewrites using a [splat](/manage/routing/redirects/redirect-options#splats) or dynamic path segment as well as rewrites for individual routes or files. This means that even if you've setup the following rewrite rule:

```
/*   /index.html   200
```

The path `/partials/chat.html` would still render the contents of that file, if that file actually exists. This tends to be the preferred behavior when setting up rewrite rules for single page apps, etc.

If you're 100% sure that you'll always want to redirect, even when the URL matches a static file, you can append an exclamation mark to the rule:

```
/app/*  /app/index.html  200!
```

This will rewrite everything within `/app/*` to `/app/index.html` even if a file matches the URL.

This method can also be applied to individual routes or files:

```
/best-pets/dogs  /best-pets/cats.html 200!
```

With the rule above, `/best-pets/dogs` will always display the content in `/best-pets/cats.html` even if there is a file at `/best-pets/dogs/index.html`.

## Proxy to another service

Similar to how you can rewrite paths like `/*` to `/index.html`, you can also set up rules to let parts of your site proxy to external services. Let's say you need to communicate from a single-page app with an API on `https://api.example.com` that doesn't support CORS requests. The following rule will let you use `/api/` from your JavaScript client:

```
/api/*  https://api.example.com/:splat  200
```

Now all requests to `/api/...` will be proxied through to `https://api.example.com` straight from our CDN servers without an additional connection from the browser. If the API supports standard HTTP caching mechanisms like ETags or `Last-Modified` headers, the responses will even get cached by our CDN nodes.

### Custom headers in proxy redirects

For redirect rules specified in the [Netlify configuration file](/manage/routing/redirects/overview#syntax-for-the-netlify-configuration-file), you can add a map with custom headers for your proxy redirects, and Netlify will send the custom headers to another website with every request:

```toml
[[redirects]]
  from = "/search"
  to = "https://api.mysearch.com"
  status = 200
  force = true
  headers = {X-From = "Netlify"}
```

### Caution - Custom headers apply to the request, not the response

If you are proxying content to your site, custom headers will not be applied to that content.

### Signed proxy redirects

You can use a [JSON Web Signature](https://en.wikipedia.org/wiki/JSON_Web_Signature) (JWS) to sign all proxy requests to an external URL.

To enable JWS on your requests, Netlify requires a secret token. You can set the token in your [site's environment variables](/build/environment-variables/overview) and indicate the variable name as the `signed` value in the redirect rule. Note that if you have the option to set specific [scopes](/build/environment-variables/overview#scopes) for your environment variables, the scope must include **Runtime** to be available for signed proxy redirects.

Netlify will inject the environment variable value automatically, so you don't need to take extra steps to [substitute the variable value](/build/configure-builds/file-based-configuration#inject-environment-variable-values) in the configuration file. Once proxy redirects are added, Netlify will send the JWS as an HMAC HS256 encoded `x-nf-sign` header to another, non-Netlify website with every proxied request.

Signed proxy redirects must be specified in the [Netlify configuration file](/manage/routing/redirects/overview#syntax-for-the-netlify-configuration-file).

```toml
[[redirects]]
  from = "/search"
  to = "https://api.mysearch.com"
  status = 200
  force = true
  signed = "API_SIGNATURE_TOKEN_PLACEHOLDER"
```

The JSON document we sign with this JWS header has this format:

```json
{
  "deploy_context": "production",
  "exp": 1623876755,
  "iss": "netlify",
  "netlify_id": "1be0f471-6532-45ff-b1b1-f9c66ea24dc1",
  "site_url": "https://mysitename.netlify.app"
}
```

### Note - Signed proxy redirects for external sites only

When proxying from one Netlify application to another, using JWS to sign requests isn't supported.

## Proxy to another Netlify site

With internal rewrites, you can proxy from one Netlify site to another. If you want to proxy to another Netlify site, we recommend using the site's `.netlify.app` subdomain instead of the custom domain in your rewrite rule:

```
/netlify-site/*  https://my-other-site.netlify.app/:splat  200
```
