Legacy URLs
Most cratly websites replace an existing one, and inherit its addresses. Every address a search engine knows and the new site does not answer is a result its owner loses — quietly, because no build and no deploy notices that a page which used to exist no longer does.
cratly's answer has three tiers, and they are ordered: the first one that fits a given address is the one to use.
1. Keep the address
A page served at the legacy path needs no redirect at all. It spends no ranking, needs nothing from the web server, and works on any static host.
---
url: kontakt.html
---url decouples a page's address from where its file lives, so a relaunch that keeps its structure — including legacy .html paths — is finished here.
2. Declare the address and let the server redirect
For addresses that cannot be files — .php, query strings, two old pages merged into one, a changed language prefix — the page names what it replaces:
---
aliases:
- /kontakt.html
- kontakt.php
---And addresses that are not coming back are named once, at site level, because they have no page to carry them:
# .cratly.config.yaml
retired_urls:
- /aktion-2019.phpOnly a server-side redirect passes an accumulated ranking on, and 301 is the status that says so. 410 for a retired address tells a search engine to drop the entry rather than keep asking.
3. Client-side redirect, as a fallback
A page that forwards in the browser — redirect — gets a visitor to the right place on a host that cannot redirect at all. Search engines follow it, but it counts for less and takes longer to be honoured, so it is a fallback and not the recommendation.
The redirect manifest
What tiers 2 and 3 amount to is written out by the adapter at the end of every build, into the build output as cratly-redirects.json:
{
"$schema": "https://cratly.io/schema/redirects/v0.json",
"specVersion": 0,
"adapter": { "name": "scavold", "version": "0.2.0" },
"rules": [
{ "from": "/kontakt.html", "to": "/de/kontakt.html", "status": 301 },
{ "from": "/aktion-2019.php", "status": 410 }
]
}from— the inherited address, site-absolute and spelled as it stood in the browser. A query string may be present; a consumer that cannot match on one should ignore the rule rather than match the path alone. No fragment: it never reaches a server.to— where the address now leads, naming the file the page is built into. Absent for410.status—301(or308where the request method must survive) and410.
Rules are sorted by from, so the file changes only when the declarations do.
The format names no web server. cratly does not assume who serves a site — s3-http, a Caddy or nginx in front of a bucket, a customer's own hosting — so the artifact carries addresses and statuses and nothing else. Grammar: /schema/redirects/v0.json.
Who reads it
The deploy step, which knows its target and writes what that target understands: an .s3-http.config.yaml, a Caddy or nginx rule set, a bucket's routing rules, a _redirects file. Consumers should evaluate the rules before looking for a file, and treat the first matching rule as the answer.
It lives in the build output rather than in the repository because it describes that build: it names the pages that build produced and changes with them, it travels with the artifact that gets uploaded, and it cannot go stale relative to the site it describes. (The section-type manifest is committed for the opposite reason: its consumer, the editor, has to read it without a build.)
What the build refuses
Two declarations cannot be served as meant, and an adapter should stop rather than pick a winner:
- two pages claiming one former address — which page a visitor reaches would come down to iteration order;
- a former address the new site serves itself — the redirect wins over the page, so the page becomes unreachable while every menu on the site still links to it.
Before the switch
The one step nothing can replace: collect the old site's addresses while it is still online. A sitemap, a crawl, an export from Search Console — anything that lists what exists today. After the switch there is no way to reconstruct it, and a redirect nobody knew was needed is indistinguishable from a page that never existed.
Keep the redirects in place afterwards for at least a year. A search engine needs to see them repeatedly before it moves the ranking across for good.
See also
- Site configuration —
aliases,retired_urls,url,redirect - ADR 0005 — why the artifact is neutral and who translates it