Who this is for. The content modeller and the site operator who look after a site's addresses. Afterwards you can predict a record's slug, explain a clash to an author, and change a live page's slug without breaking its links.
How a slug is generated
When a record is first saved without a slug, the platform makes one from its name: lower case, accented letters transliterated, and every run of other characters turned into one hyphen, so Opening hours & prices becomes opening-hours-prices. For a category or a tag, +, , and / become hyphens first, since those characters mean something in the listing URLs. If the slug is already taken where it has to be unique, a number is appended: -1, then -2, and so on.
This happens once, on the first save. Renaming a record later never changes its slug, so a page renamed from Summer sale to Winter sale still answers at /summer-sale until someone edits the slug. A slug an author types is checked: it may hold letters, digits, hyphens and underscores, and anything else is refused with "This value is not a valid slug."
What a slug must be unique against
| Record | Unique among |
|---|---|
| Pages, books, units and book pages | The records under the same parent, on the same site |
| FAQ pages | The FAQ pages under the same parent, on the same site |
| Blog posts | The posts of the same blog |
| Blogs, FAQ questions | All blogs, or all questions, of the site |
| Custom entity records | The records of the same definition, across every site of the account |
| Categories, tags | Those of the same site, or the account-wide ones |
So two pages can both be called pricing if they sit under different parents, while two questions on one site cannot share a slug wherever they are listed. A clash an author makes by hand is refused when the record is saved, with "This value is already used." on the slug field. Custom entity records are the case that surprises: a record on one site and a record of the same definition on another cannot share a slug, even when the definition is site-specific.
Editing the slug of a live page
Changing a slug changes the record's address at once, and for a page, book or unit the address of everything beneath it. The platform creates no redirect: from the next request the old address answers 404, and every link to it from outside the site, from search results and from bookmarks breaks. Do two things in the same change:
- Add a redirect for each old address, as a rewrite with an exact match from the old path to the new one, Permanent (301) when the move is for good. For a page with children, one redirect per moved page, or one regular-expression rewrite that maps the old prefix to the new one. Rewrites, redirects and which address wins covers both.
- Check that the site links to records, not to typed paths. Templates that print
getFullPath()follow the change by themselves; a path typed into a richtext area or a menu does not.
A job can make the first step automatic: the page's update event carries the fields that changed, the old slug among them, and a job's action can create a rewrite record (Events, what starts a job).