Skip to main content

Content

Redirects

Map old URLs to new ones with wildcards, permanent or temporary HTTP status codes, and tail preservation — all config-driven, zero code.

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/guides308 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[].sourcestringpathrequired

URL path to match. Must start with /. Trailing /* enables prefix matching.

redirects[].destinationstringpathrequired

Where 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: false

HTTP 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=bar doesn't participate in matching, but query strings pass through: hitting /old?x=1 with a redirect to /new sends you to /new?x=1 (query preserved).

Related

Was this page helpful?

Last updated August 10, 2026