Redirects
Redirects and wildcard redirects.
On this page
Enable the Redirects collection by passing redirect: true to withSysthema():
const config = withSysthema(buildConfig({ /* ... */ }), {
redirect: true,
})This registers @payloadcms/plugin-redirects's redirects collection. Editors author redirects in the admin panel under Redirects.
Stored fields and accessLink to this section
Each row has from, a custom URL or document-reference destination, the redirect status and preserveQueryString. Creating, reading, updating and deleting redirect rules uses the corresponding redirects.* capabilities. Change and delete hooks revalidate the site so cached redirect behavior is refreshed. Reference destinations require a resolvable document path.
Wildcard redirectsLink to this section
When a from path contains *, Systhema treats it as a wildcard redirect and matches it automatically — no toggle needed.
from syntaxLink to this section
Each * captures part of the path. A * at the end of the pattern captures everything that follows, including slashes. A * with more pattern after it captures a single segment (no slashes).
from pattern | Matches |
|---|---|
/blog/* | Everything under /blog/ — /blog/hello and /blog/2024/recap (a trailing * captures the rest, including slashes) |
/shop/*/reviews | A single segment — /shop/widget/reviews, but not /shop/a/b/reviews (a * with more pattern after it matches one segment) |
/*/news/* | Two captures — first * (has /news/… after it) = one segment; second * (trailing) = the rest; reorder via $1, $2 |
to syntax (custom URL target)Link to this section
| Target value | Behaviour |
|---|---|
/posts/* | Bare * — substituted with the first capture ($1) |
/posts/$1 | Explicit numbered capture — same as bare * |
/news/$2-$1 | Reorders two captures |
If the target is a reference (a Payload document relationship) rather than a custom URL, all matching paths redirect to that single document — no capture substitution.
Worked exampleLink to this section
| From | To | Incoming path | Redirects to |
|---|---|---|---|
/blog/* | /posts/* | /blog/2024/recap | /posts/2024/recap |
/*/news/* | /news/$2-$1 | /world/news/recap | /news/recap-world |
Same-origin safetyLink to this section
A custom-URL target stays on your own site: if a captured value would turn the resolved target into an absolute (http://…) or protocol-relative (//…) URL, the redirect is rejected and the next rule is tried — a capture can't smuggle in an off-site destination. Intentional off-site redirects still work; declare the host in the target itself (e.g. https://example.com/*), so the off-origin part comes from your literal template rather than from a capture.
Resolution orderLink to this section
Within the site catch-all, resolution runs:
- Exact redirects (from the
redirectscollection, no wildcards) — matched first. - Wildcard redirects — matched next, most-specific rule wins (the rule with the most literal characters in
fromtakes precedence). - Page lookup — only reached if no redirect matched.
- Post permalink lookup — with the Posts module enabled, only when no page matched at the path.
So an authored wildcard redirect wins over still-existing content at the same path. With the Posts module enabled, a redirect's reference target can also point at a post — it resolves through the permalink engine.
Status codesLink to this section
308 permanent is the default. Editors can change it to 307 temporary per redirect on the standard Payload Redirects form.
Preserve query stringLink to this section
Every redirect — exact and wildcard alike — has an Advanced Settings collapsible containing a Preserve query string checkbox (default on). When on, the incoming ?query=string is carried over to the target URL — target params win on conflict. Uncheck it to drop the query string entirely.
Redirects and localesLink to this section
With locales enabled, from and a custom to.url are localized: each locale has its own pair, so /about → /contact in English and /rolunk → /kapcsolat in Hungarian live on one row. An incoming request is matched against the from of its own locale only — a Hungarian path never matches an English from. Leave a locale's from empty and that row simply doesn't apply there.