> ## Documentation Index
> Fetch the complete documentation index at: https://docs.slipway.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Redirects and headers

> Route paths and set response headers on a static site, without a redeploy.

A static site's redirects, rewrites and response headers can be set in three places. All
three compile into one set of rules the CDN evaluates on every request.

> [!NOTE]
>
> These rules apply to `type: static` services only. A web service's routing is its own
> application's business.

## The three sources

| Source | Lives in | Changing it needs |
| - | - | - |
| `slipway.yaml` | Your repo | A deploy |
| `_redirects` and `_headers` | Your build output | A deploy |
| The **Redirects** and **Headers** tabs | slipway | Nothing. Applied in about a minute. |

The console tabs are the only source that rebuilds nothing. A site's compiled rules travel
inside the pointer the CDN reads, so saving rewrites one record, the same single write that
performs a [rollback](/deploys/rollback). Nothing is rebuilt or re-uploaded, and no cache
is purged.

## Which rule wins

Console rules win. They compile last, so where two rules cover the same path, the one set in
slipway applies.

Both tabs show your repo's rules underneath your own, read-only, so you can see which rule
is shadowing which.

> [!NOTE]
>
> Redirects list console rules **first** and headers list them **last**. The outcome is the
> same in both cases: the edge takes the first matching redirect and the last matching
> header.

## Redirects and rewrites

A redirect sends the browser somewhere else. A rewrite, status `200`, serves a different
file without changing the URL.

| Field | Example | Notes |
| - | - | - |
| Source | `/old/*` | Must start with `/`. `*` matches the rest of the path and may only appear at the end. `:name` matches one segment. |
| Destination | `/new/:splat` | A path on this site, or a full URL for a redirect. |
| Status | `301` | `301` permanent, `302` temporary, `200` rewrite, `404` hide a path. `307` and `308` are also accepted. |

```
/blog/:slug     /posts/:slug        301
/old-docs/*     /docs/:splat        301
/app/*          /app/index.html     200
```

In the spec:

```yaml slipway.yaml theme={"system"}
services:
  - name: site
    type: static
    publish: dist
    notFound: /index.html
    redirects:
      - from: /old-docs/*
        to: /docs/:splat
        status: 301
```

Rules match top to bottom and the first match wins, so put specific rules above catch-alls.

If you omit `status`, slipway uses `301`.

> [!WARNING]
>
> A `200` rewrite can only point at a path on your own site. Rewrites are served by slipway
> from the target, so an external one would make the edge an open proxy serving someone
> else's content on your bandwidth. A `301` or `302` to an external URL is fine, because the
> browser goes there itself.

## Response headers

One row per header: a path to match, a header name and its value.

```
/assets/*     Cache-Control          public, max-age=604800
/*            X-Content-Type-Options nosniff
```

In the spec:

```yaml slipway.yaml theme={"system"}
services:
  - name: site
    type: static
    publish: dist
    headers:
      - for: /assets/*
        values:
          Cache-Control: public, max-age=604800
```

Later rules win, so a specific path below a broad one overrides it.

These headers cannot be set: `Content-Length`, `Content-Encoding`, `Transfer-Encoding`,
`Connection` and `Host`. The edge owns them, and overriding them produces a response that
lies about itself.

## SPA routing

For a single-page app, set `notFound` so unmatched paths serve the app shell:

```yaml slipway.yaml theme={"system"}
services:
  - name: site
    type: static
    publish: dist
    notFound: /index.html
```

## When a change takes effect

About a minute at worst. The edge caches the routing record for up to 60 seconds, so a save
reaches every location within roughly that.

Nobody ever sees a half-applied set. The rules are written as one record, so every request
is served with either all of your old rules or all of your new ones.

## Deploys do not undo console rules

Rules set in the console are stored against the service rather than against a build, so
they survive redeploys and rollbacks. A rollback restores the old files with your current
rules, which is usually what you want, since a rollback is normally about the build rather
than the routing.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.