# Redirects

Configure URL redirects to manage page moves, URL changes, and legacy paths in your documentation site.

## Overview

Redirects allow you to automatically send visitors from one URL to another. This is essential when you reorganize your documentation structure, rename pages, or need to maintain backward compatibility with old URLs.

Redirects are processed at the middleware level before any page rendering occurs. The first matching redirect in your configuration takes precedence.

## When to use redirects

Common use cases for redirects include:

- **Page moves**: Redirect old URLs when you reorganize your documentation structure
- **URL changes**: Maintain links when renaming pages or changing URL slugs
- **Legacy support**: Keep old bookmarks and external links working
- **Content consolidation**: Redirect multiple old pages to a single new page
- **Version migrations**: Redirect users from deprecated API versions to current ones

## Configuration

Redirects are configured in your `documentation.json` file under the `redirects` property:

```
{
  "redirects": [
    {
      "source": "/old-page",
      "destination": "/new-page"
    }
  ]
}
```

## Redirect properties

| Property         | Type                  | Required | Description                                                                                          |
| ---------------- | --------------------- | -------- | ---------------------------------------------------------------------------------------------------- |
| `source`        | `string`             | Yes      | The incoming path pattern to match. Supports dynamic segments with `:paramName` syntax.             |
| `destination`   | `string`             | Yes      | The target path to redirect to. Can include dynamic parameters from the source.                      |
| `statusCode`    | `301 | 302 | 307 | 308` | No       | HTTP status code for the redirect. Defaults to `308`.                                               |

## Status codes

Choose the appropriate status code based on your redirect scenario:

| Code | Name                  | Use Case                                                                                        |
| ---- | --------------------- | ------------------------------------------------------------------------------------------------- |
| `301` | Moved Permanently     | Permanent redirect. May change request method to GET. Best for SEO when content has permanently moved. |
| `302` | Found                 | Temporary redirect. May change request method to GET. Use for temporary moves.                   |
| `307` | Temporary Redirect     | Temporary redirect that preserves the request method. Use for temporary moves with POST/PUT requests. |
| `308` | Permanent Redirect      | Permanent redirect that preserves the request method. **Default**. Best for permanent moves.       |

Use `308` (the default) for most permanent redirects. It's the modern replacement for `301` and preserves the HTTP method, which is important for API documentation.

## Basic redirects

### Simple page redirect

Redirect a single page to a new location:

```
{
  "redirects": [
    {
      "source": "/old-page",
      "destination": "/new-page"
    }
  ]
}
```

### Multiple redirects

Define multiple redirects in the array:

```
{
  "redirects": [
    {
      "source": "/getting-started",
      "destination": "/docs/quickstart"
    },
    {
      "source": "/api-docs",
      "destination": "/api-reference"
    },
    {
      "source": "/faq",
      "destination": "/support/faqs"
    }
  ]
}
```

### Redirect with custom status code

Specify a status code for temporary or specific redirect behaviors:

```
{
  "redirects": [
    {
      "source": "/maintenance",
      "destination": "/status",
      "statusCode": 307
    },
    {
      "source": "/legacy-api",
      "destination": "/v2/api",
      "statusCode": 301
    }
  ]
}
```

## Dynamic redirects

Dynamic redirects use path parameters to match patterns and transfer values to the destination URL.

### Parameter syntax

Use `:paramName` syntax to define dynamic segments:

```
{
  "redirects": [
    {
      "source": "/docs/:slug",
      "destination": "/documentation/:slug"
    }
  ]
}
```

This redirect matches:

- `/docs/quickstart` → `/documentation/quickstart`
- `/docs/api-reference` → `/documentation/api-reference`
- `/docs/getting-started` → `/documentation/getting-started`

### Multiple parameters

You can use multiple parameters in a single redirect:

```
{
  "redirects": [
    {
      "source": "/api/:version/:endpoint",
      "destination": "/reference/:version/:endpoint"
    }
  ]
}
```

This redirect matches:

- `/api/v1/users` → `/reference/v1/users`
- `/api/v2/products` → `/reference/v2/products`

### Reorganizing parameters

Parameters can be reordered or selectively used in the destination:

```
{
  "redirects": [
    {
      "source": "/blog/:year/:month/:slug",
      "destination": "/articles/:slug"
    }
  ]
}
```

This redirect matches:

- `/blog/2024/01/my-post` → `/articles/my-post`

Dynamic parameters only match single path segments. The pattern `/docs/:slug` will match `/docs/quickstart` but will **not** match `/docs/api/users` (which has two segments after `/docs/`).

## Pattern matching behavior

Understanding how redirects match URLs helps you configure them correctly.

### Trailing slashes

Trailing slashes are normalized during matching. Both `/docs/` and `/docs` will match a source pattern of `/docs`:

```
{
  "redirects": [
    {
      "source": "/docs",
      "destination": "/documentation"
    }
  ]
}
```

Matches both:

- `/docs` → `/documentation`
- `/docs/` → `/documentation`

### Case sensitivity

Path matching is **case-sensitive**. `/Docs` will not match a source of `/docs`:

```
{
  "redirects": [
    {
      "source": "/docs",
      "destination": "/documentation"
    }
  ]
}
```

- `/docs` → `/documentation` ✓
- `/Docs` → No match ✗

### Segment count matching

The number of path segments must match exactly. A pattern with two segments won't match a path with three segments:

```
{
  "redirects": [
    {
      "source": "/docs/:slug",
      "destination": "/documentation/:slug"
    }
  ]
}
```

- `/docs/quickstart` → `/documentation/quickstart` ✓ (2 segments)
- `/docs/api/users` → No match ✗ (3 segments)

## Processing order

Redirects are processed in the order they appear in your configuration array. The **first matching redirect wins**.

Place more specific redirects before general ones to ensure they take precedence.

```
{
  "redirects": [
    {
      "source": "/docs/api/deprecated",
      "destination": "/docs/api/v2"
    },
    {
      "source": "/docs/:slug",
      "destination": "/documentation/:slug"
    }
  ]
}
```

In this example:

- `/docs/api/deprecated` matches the first rule (specific)
- `/docs/quickstart` matches the second rule (general)

## Subpath deployments

If your documentation is deployed at a subpath (e.g., `example.com/docs`), redirects are automatically adjusted:

- The subpath is prepended to the `source` for matching
- The subpath is prepended to the `destination` if not already present

You don't need to include the subpath in your redirect configuration:

```
{
  "redirects": [
    {
      "source": "/old-page",
      "destination": "/new-page"
    }
  ]
}
```

For a subpath deployment at `/docs`:

- Request to `/docs/old-page` → Redirects to `/docs/new-page`

## Examples

### Documentation restructure

When reorganizing your documentation hierarchy:

```
{
  "redirects": [
    {
      "source": "/guides/getting-started",
      "destination": "/quickstart"
    },
    {
      "source": "/guides/installation",
      "destination": "/getting-started/installation"
    },
    {
      "source": "/guides/configuration",
      "destination": "/getting-started/configuration"
    },
    {
      "source": "/reference/api",
      "destination": "/api-reference/overview"
    }
  ]
}
```

### API version migration

When deprecating an API version:

```
{
  "redirects": [
    {
      "source": "/api/v1/:endpoint",
      "destination": "/api/v2/:endpoint",
      "statusCode": 301
    },
    {
      "source": "/api/v1",
      "destination": "/api/v2",
      "statusCode": 301
    }
  ]
}
```

### Content consolidation

When merging multiple pages into one:

```
{
  "redirects": [
    {
      "source": "/troubleshooting/errors",
      "destination": "/support/troubleshooting"
    },
    {
      "source": "/troubleshooting/faq",
      "destination": "/support/troubleshooting"
    },
    {
      "source": "/help/common-issues",
      "destination": "/support/troubleshooting"
    }
  ]
}
```

### Temporary maintenance redirect

When temporarily redirecting during maintenance:

```
{
  "redirects": [
    {
      "source": "/api-playground",
      "destination": "/maintenance",
      "statusCode": 307
    }
  ]
}
```

## Best practices

- Keep redirects organized
- Use permanent redirects for SEO
- Test redirects before deploying
- Avoid redirect chains
- Monitor redirect performance

## Troubleshooting

- Redirect not working
- Wrong destination URL
- Redirect loops
- Dynamic parameters not working
