Generates redirect files from page aliases and global redirect mappings. Outputs HTML meta-refresh pages as a universal fallback, plus platform-specific files for Netlify/Cloudflare (_redirects) and Vercel (vercel.json). Enabled by default.
Redirect sources
Redirects come from three places, merged at build time:
- Global redirects in
sarde.yaml(theredirectsmap) - Page aliases in frontmatter (the
aliasesfield) - Old URLs of date-prefixed posts: the URL Sarde 1.5 gave a file such as
2026-03-15-hello.md(/blog/03-15-hello/). See Date filename prefixes.
Page aliases override global redirects when both define the same source path. An old date-prefix URL is added only when no page, alias or global redirect already uses that path.
Global redirects
Define source-to-target path mappings in sarde.yaml:
sarde.yaml
redirects: /old-page/: /new-page/ /legacy/guide/: /docs/guides/writing-content/ /blog/2023/announcement/: /blog/2024/update/Each key is the old URL path. Each value is the target URL path.
Page aliases
Add an aliases list to any page's frontmatter. Each alias creates a redirect from that path to the page's current URL.
---title: Writing Contentaliases: - /docs/authoring/ - /docs/writing-markdown/---→ Visiting /docs/authoring/ or /docs/writing-markdown/ redirects to the current page URL.
Output formats
The plugin generates up to three output formats per redirect.
HTML meta-refresh (always generated)
For each redirect, an HTML file is written at the source path. The file uses <meta http-equiv="refresh"> and a <link rel="canonical"> pointing to the target. This works on any static hosting provider.
For a redirect from /old-page/, the file is written to old-page/index.html. Paths ending in .html are written as-is.
Netlify/Cloudflare _redirects
A _redirects file is generated at the site root with one line per redirect:
/old-page/ /new-page/ 301/legacy/guide/ /docs/guides/writing-content/ 301All redirects use status code 301 (permanent).
Netlify serves an existing file in place of a plain _redirects rule for the same path, and the plugin always writes an HTML page at each source path. When the site targets Netlify, through deploy.provider: netlify or deploy.redirect_format: netlify, each rule is forced with 301!, so Netlify answers with the 301 instead of the HTML page:
/old-page/ /new-page/ 301!Every other target keeps the plain 301. Cloudflare Pages applies its _redirects rules ahead of files, so the HTML pages do not get in the way there. See Netlify.
Vercel vercel.json
A vercel.json file is generated at the site root:
{ "redirects": [ { "source": "/old-page/", "destination": "/new-page/", "permanent": true } ]}Vercel reads this file when sarde deploy or the Vercel CLI uploads dist/, but not when Vercel builds the site from Git. See Vercel.
Controlling output formats
Set deploy.redirect_format in sarde.yaml to control which platform files are generated. HTML meta-refresh files are always written regardless of this setting.
sarde.yaml
deploy: redirect_format: netlify| Value | _redirects |
vercel.json |
|---|---|---|
"" (default) |
Yes | Yes |
"all" |
Yes | Yes |
"netlify" |
Yes | No |
"vercel" |
No | Yes |
Disabling redirects
Remove redirects from the enabled list:
plugins: enabled: - search - seo - sitemap - robots - rss - atom - content_lint - link_validator # redirects removedThe build still writes an HTML redirect page at each page alias. The redirects map in sarde.yaml produces nothing, and no _redirects or vercel.json file is written.
Edge cases
- When a page alias conflicts with a global redirect for the same source path, the page alias wins.
- Source paths without a trailing slash or
.htmlextension getindex.htmlappended (e.g.,/old-pagebecomesold-page/index.html). - Output is deterministic: redirects are sorted alphabetically by source path.
- Target URLs in HTML output are sanitized:
",<, and>characters are percent-encoded. - If no redirects exist (no aliases and no global mappings), no files are written.