Redirects
Per-website redirect rows with 301 or 302, an optional locale, and [param] patterns. Redirects are matched before pages.
Rows
A redirect has a from, a to, a status (301 or 302), and an optional locale. to may be an absolute URL. Rows are per website.
from and to accept a space or %20. Each segment is decoded once, NFC-normalized, and stored percent-encoded with uppercase hex. [param] segments are kept, and an encoded slash stays inside its segment.
A from that ends in a static asset extension is saved with a warning, because the public proxy does not apply redirects to assets.
Testing
test_redirect reports the status and Location the proxy would send for a stored path, without changing anything. It answers 404 when no page matches, 301/302 for a stored row, and 308 for a locale-path alias.
Automatic redirects
Changing a localized identifier segment, or changing an object type's identifier field, writes a locale-scoped 301 so existing links keep working. Publishing a new path pattern can also create 301s for the previous pattern.
Order of resolution
Static asset check, then stored redirects, then locale aliases, then the page router. A dynamic route still matches when its slug contains a period.