stencila.toml_redirect.json
Config redirects
[site.routes]stencila.toml{name}*
[site.routes]
# Exact redirect
"/old-page" = { redirect = "/new-page", status = 301 }
# Splat — * matches all remaining path segments
"/blog/*" = { redirect = "https://blog.example.com/{splat}", status = 301 }
# Placeholders — {name} matches a single path segment
"/docs/{lang}/{page}" = { redirect = "/documentation/{lang}/{page}" }
# Combined placeholder and splat
"/products/{category}/*" = { redirect = "/shop/{category}/{splat}", status = 301 }
# External redirect (defaults to 307)
"/legacy/" = { redirect = "https://legacy.example.org" }Fields
redirect | {name}{splat} | ||
status | 301302303307308307 |
Patterns
Exact match
"/old-page" = { redirect = "/new-page", status = 301 }Splats ( *)
**{splat}
"/blog/*" = { redirect = "https://blog.example.com/{splat}", status = 301 }{splat} | ||
|---|---|---|
/blog/ | https://blog.example.com/ | |
/blog/hello | hello | https://blog.example.com/hello |
/blog/2024/my-post | 2024/my-post | https://blog.example.com/2024/my-post |
*
Placeholders ( {name})
{name}{name}{name}
"/docs/{lang}/{page}" = { redirect = "/documentation/{lang}/{page}" }/docs/en/intro | lang=enpage=intro | /documentation/en/intro |
/docs/fr/guide | lang=frpage=guide | /documentation/fr/guide |
/docs/en | ||
/docs/en/intro/extra |
Combining splats and placeholders
"/products/{category}/*" = { redirect = "/shop/{category}/{splat}", status = 301 }/products/shoes/ | /shop/shoes/ |
/products/shoes/nike/air-max | /shop/shoes/nike/air-max |
Rule ordering
[site.routes]
[site.routes]
# Specific rule first
"/blog/archive" = { redirect = "/blog/all", status = 301 }
# Catch-all after
"/blog/*" = { redirect = "https://blog.example.com/{splat}", status = 301 }/blog/archive/blog/all
Destination URLs
https://example.com/page | ||
/new-path | ||
../other |
http:https:
"/search" = { redirect = "/find?source=redirect" }Choosing a status code
301 | ||
302 | ||
303 | GET | |
307 | ||
308 | 307 |
use 301for permanent page moves use 307for temporary moves or maintenance redirects use 302only when you specifically want classic temporary redirect behavior use 303mainly for non-page workflows use 308when permanent method-preserving behavior matters
Per-directory redirects
_redirect.json
{
"location": "/docs/",
"status": 301
}location | |||
status | 301302303307308307 |
/index.html
_redirect.jsonstencila.toml
Example
_redirect.jsonold-docs/
{
"location": "/docs/",
"status": 301
}/old-docs/ | /docs/ |
/old-docs/guide/ | _redirect.jsonold-docs/guide/ |
Resolution order
Static file — serve the file if it exists Per-directory _redirect.json— checked for route requests when no index.htmlexists Root-level _redirects.json— config redirects checked for any unmatched path 404 — if nothing matches
Constraints
/a/*/a/*/b | |
* | |
/ | |
301302303307308302 | |
httphttps | |
_redirect.json_redirects.json |