Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion docs/authoring/redirects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ When you change a published URL, update three things: the file at the new path,
</Steps>

<Info>
Keep the stub file at the old path even after the content lives elsewhere. Deleting the stub removes the old URL entirely.
Keep the stub file at the old path even after the content lives elsewhere. Deleting the stub removes the old URL entirely — unless you forward it from the `redirects` map in `docs.json` (see [Forward deleted pages in bulk](#forward-deleted-pages-in-bulk)).
</Info>

## Add a redirect stub
Expand Down Expand Up @@ -64,6 +64,21 @@ Leave a minimal file at the **old** path and set `redirect` in frontmatter to th
Do not rely on query strings or hash anchors in `redirect` values. They are not part of the redirect contract.
</Warning>

## Forward deleted pages in bulk

Stubs work when you keep a file at the old path. When you **delete** pages outright — or need to forward many old URLs at once — add a centralized `redirects` map to `docs.json` instead of leaving a file behind for each one:

```json title="docs.json"
"redirects": {
"/installation": "/getting-started",
"/old-api": "https://api.example.com/reference"
}
```

Keys are the old root-relative paths; values are internal paths or external `https://` URLs. docs.page consults this map **only when no file exists at the requested path**, so it is the tool for URLs whose files were removed. Keep frontmatter stubs for the case where a file still lives at the old path.

See [`redirects`](/reference/docs-json#redirects) and [Redirects → The centralized redirects map](/features/redirects#the-centralized-redirects-map).

## Verify the redirect

After you add or change redirect stubs:
Expand Down
21 changes: 19 additions & 2 deletions docs/features/redirects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ redirect: /getting-started
---
```

docs.page returns a **307 Temporary Redirect** to the destination before any page body renders. Redirects are **per page file**, not a central table in `docs.json` — one old URL, one stub.
docs.page returns a **307 Temporary Redirect** to the destination before any page body renders. You can declare redirects two ways: a per-page `redirect` in frontmatter (above) for URLs whose file you keep, or a centralized `redirects` map in `docs.json` for old URLs whose files were removed. See [The centralized redirects map](#the-centralized-redirects-map).

For step-by-step rename workflows, see [Redirects](/authoring/redirects). Field syntax and other frontmatter options live in [Page frontmatter](/reference/page-frontmatter).

Expand All @@ -37,6 +37,23 @@ redirect: https://example.com/docs/new-location

The file body can be empty. Only `redirect` is required for the HTTP redirect. Other frontmatter fields are ignored at request time. Do not rely on query strings or hash anchors in `redirect` values. They are not part of the redirect contract.

### The centralized redirects map

A per-page stub covers one old URL each. When you **delete** a page and still want its old URL to forward somewhere, add an entry to the top-level `redirects` object in `docs.json` instead of leaving a file behind:

```json title="docs.json"
"redirects": {
"/old-guide": "/guides/getting-started",
"/legacy-api": "https://api.example.com/reference"
}
```

Keys are old root-relative doc paths; values are the destinations. Keys and values are matched tolerant of leading and trailing slashes, and values follow the same internal/external rules as frontmatter `redirect`: root-relative paths resolve against the current routing mode and ref, while `http(s)://` and `//` URLs are returned unchanged. A match issues the same **307 Temporary Redirect**.

The map is consulted **only on the 404 branch** — that is, only when no `.mdx` file exists at the requested path. If a file still lives at that path, docs.page renders it (or follows its own frontmatter `redirect`) and never looks at the config map. Use the map for old URLs whose files were removed; use a frontmatter stub when you keep a file at the old path.

See [`redirects`](/reference/docs-json#redirects) in the docs.json reference.

### How internal paths resolve across routing modes

Internal redirects stay on the same site **mode** as the request. docs.page picks a base URL from the active route, appends the current ref segment when present, then appends your path.
Expand All @@ -58,7 +75,7 @@ You do not hard-code `https://docs.page/owner/repo` in frontmatter for internal

| Topic | Behavior |
| --- | --- |
| Definition | Per-page `redirect` in frontmatter only; no wildcard or catch-all rules in `docs.json` |
| Definition | Per-page `redirect` frontmatter, or a centralized `redirects` map in `docs.json`; no wildcard or pattern matching — keys are exact paths (slash-tolerant) |
| HTTP status | Temporary redirect (307), not permanent (308) |
| Deleted files | Removing the stub removes the URL. Keep the old file to preserve the path |
| Validation | [`docs check`](/features/cli#check-documentation) validates redirect targets the same way it validates in-page links |
Expand Down
19 changes: 19 additions & 0 deletions docs/reference/docs-json.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Site configuration lives in `docs.json` or `docs.yaml` at the repository root. F
| `logo`, `favicon`, `banner`, `theme` | [logo](#logo), [favicon](#favicon), [banner](#banner), [theme](#theme) |
| `header`, `tabs`, `sidebar`, `anchors` | [header](#header), [tabs](#tabs), [sidebar](#sidebar), [anchors](#anchors) |
| `content`, `seo`, `variables` | [content](#content), [seo](#seo), [variables](#variables) |
| `redirects` | [redirects](#redirects) |
| `scripts`, `search`, `social`, `og` | [scripts](#scripts), [search](#search), [social](#social), [og](#og) |
| `agent`, `mcp` | [agent](#agent), [mcp](#mcp) |

Expand Down Expand Up @@ -323,6 +324,24 @@ See [Links](/features/links).
Only **string** leaf values substitute. Intermediate objects are traversed; non-string leaves leave the placeholder unchanged. Variables do not apply inside frontmatter. See [Global variables](/features/global-variables).
</Property>

## redirects

<Property name="redirects" type="object">
Centralized `{ "from": "to" }` map for forwarding old URLs whose page files were removed. Keys are old root-relative doc paths; values are the destinations. Keys and values are matched tolerant of leading and trailing slashes.

```json
"redirects": {
"/old-guide": "/guides/getting-started",
"installation/setup": "/getting-started",
"/legacy-api": "https://api.example.com/reference"
}
```

Values may be internal root-relative paths (resolved against the current routing mode and ref, like frontmatter `redirect`) or external `http(s)://` / `//` URLs (returned unchanged). Each match issues a **307 Temporary Redirect**.

This map is consulted **only when no `.mdx` file exists at the requested path** (a deleted or moved page). When a file is still present, its own frontmatter `redirect` governs instead. See [Redirects](/features/redirects).
</Property>

## scripts

Analytics and tag-manager injection on **published** pages only, not during local preview.
Expand Down
Loading