Redirects keep inbound links alive after you rename a page, reshuffle navigation, or migrate from another platform. NookDocs applies them at the docs-page layer before any lookup — if an incoming URL matches a redirect entry, the reader gets a 307 / 308 response pointing to the new URL.
All config-driven via nookdocs.config.json#redirects. No filesystem, no middleware, no rebuild.
Quick start
{
"redirects": [
{ "source": "/old/guides", "destination": "/guides", "permanent": true }
]
}Deploy. Every hit to /old/guides → 308 Permanent Redirect → /guides.
How matching works
Exact match first
The incoming path is compared against each entry's source verbatim. First match wins.
Wildcard prefix match
When source ends with /*, the entry matches any path starting with the prefix. Example: /old/* matches /old/foo, /old/a/b/c, /old.
Tail preservation
When BOTH source and destination end with /*, the matched tail is preserved in the destination. /blog/* → /articles/* applied to /blog/2024/hello produces /articles/2024/hello.
HTTP status
permanent: true returns 308 Moved Permanently. permanent: false (default) returns 307 Temporary Redirect. Use 308 for permanent moves so search engines transfer ranking signals.
Config reference
redirects[].sourcestringpathrequiredURL path to match. Must start with /. Trailing /* enables prefix matching.
redirects[].destinationstringpathrequiredWhere to send the visitor. Can be a path on your docs (/new/path) or an absolute URL (https://old.example.com/page). When both source and destination end with /*, the matched tail appends.
redirects[].permanentbooleanpathdefault: falseHTTP status: true → 308 (permanent, SEO signals transfer), false → 307 (temporary, no signal transfer). Default false for safety — bump to true once you're confident the old URL shouldn't come back.
Common patterns
Single page rename
{
"redirects": [
{
"source": "/old-slug",
"destination": "/new-slug",
"permanent": true
}
]
}Folder flatten / deepen
{
"redirects": [
{ "source": "/guides/advanced", "destination": "/advanced-guides" },
{ "source": "/v1/api", "destination": "/api-reference" }
]
}Wildcard sub-tree move
{
"redirects": [
{
"source": "/blog/*",
"destination": "/articles/*",
"permanent": true
}
]
}/blog/hello → /articles/hello, /blog/a/b → /articles/a/b, /blog → /articles.
Wildcard to single destination
Omit /* on the destination to redirect an entire prefix to one page:
{
"redirects": [
{
"source": "/old/*",
"destination": "/migration-notice",
"permanent": false
}
]
}/old/anything/here → /migration-notice.
Redirect to an external URL
{
"redirects": [
{
"source": "/support",
"destination": "https://help.acme.com",
"permanent": false
}
]
}Platform migration bulk entries
When migrating from Mintlify / Docusaurus / GitBook, the old platform's URL structure is usually different. Add an entry per old path so inbound search-engine hits don't 404:
{
"redirects": [
{ "source": "/essentials/markdown", "destination": "/content/format-text", "permanent": true },
{ "source": "/essentials/code", "destination": "/content/format-code", "permanent": true },
{ "source": "/essentials/images", "destination": "/content/images-embeds", "permanent": true },
{ "source": "/quickstart/*", "destination": "/quickstart", "permanent": true }
]
}The migrate-from-mintlify CLI generates these automatically for you.
Edit from the dashboard
Configurations → SEO → Redirects exposes a form-backed editor — no JSON hand-editing required. Each row has source / destination / permanent toggle. The panel writes back to nookdocs.config.json via a git commit on save, so dashboard edits and hand-edits stay in sync.
Order matters
Redirects are evaluated top-to-bottom. The first match wins. Order specific rules before generic ones:
{
"redirects": [
{ "source": "/old/premium", "destination": "/pricing" },
{ "source": "/old/*", "destination": "/archive" }
]
}If you flipped the order, /old/premium would match /old/* first and land on /archive — not what you want.
Limitations
No regex matching. Only exact and trailing-wildcard (
/*) patterns. For complex rewriting logic you need a reverse proxy in front of your domain.No status-code override. 307 / 308 only. No 301, 302, 303, 410 options.
No request header / cookie conditions. Redirects are path-only. Conditional redirects (e.g. by geo or auth state) need middleware.
No query-string matching.
?foo=bardoesn't participate in matching, but query strings pass through: hitting/old?x=1with a redirect to/newsends you to/new?x=1(query preserved).
Related
Schema reference — redirects — auto-generated field listing
Site settings — banner, SEO, footer, navbar configuration
Migrating from Mintlify — auto-generated redirect entries during CLI migration
Custom domain — canonical URL + multi-domain handling