A documentation page’s URL is its folder location. Nothing else contributes to it:
/{page type path}/{folder names, slugified}/{page slug}/Three consequences follow, and the rest of this page will not make sense without them.
- No frontmatter key sets the URL. A page’s published file carries
title,slug,summary,pageIdand the rest — but not its path. There is nothing to edit. - A
pathsent to the create endpoint is ignored, deliberately, for a documentation page type with a bound menu. The shipped comment gives the reason: so the URL can never contradict the page’s actual menu placement. The update endpoint does not acceptpathat all. - The documentation left menu is therefore the only place folder placement is edited, and saving it physically moves pages.
How a path is composed in general — both lanes drawn out, with the -2 de-duplication loop — is at URL Paths and Slugs. This page is about what folders do to it.
The folder’s name is the URL segment, not its tooltip
The menu item dialog offers a folder both a name and a Tooltip, and only one of them is load-bearing:
| Field | Where you edit it | What it does to the URL |
|---|---|---|
| Name | Double-click the folder in the tree | Slugified into the path segment for every page beneath it |
| Tooltip | The gear dialog | Nothing. It is hover text |
So renaming a folder moves every page under it. Renaming its tooltip moves nothing. If you meant to relabel a section without touching URLs — and you often do — there is no way to do it: the label is the segment. Change the tooltip, or accept the move.
What slugification does to a folder name
Folder names are slugified with the same slugifier Leed uses everywhere. Ampersands become and, spaces become hyphens, punctuation is dropped, and everything is lowercased.
| Folder name | URL segment |
|---|---|
Getting Started | getting-started |
Pages & Editing | pages-and-editing |
AI & MCP | ai-and-mcp |
Media & Assets | media-and-assets |
Documentation Sites | documentation-sites |
Leed Markdown Format | leed-markdown-format |
There is no separate slug field on a folder, so choose folder names whose slug is the URL segment you want. That is not a style preference; it is the only control you have. This documentation set is the worked example: every folder in its left menu is named so that its slug is exactly the URL segment we wanted, which is why the set could be reorganized during authoring without a single redirect.
The page’s own slug
The last segment is the page’s slug, and it is derived from the title — slugified, then de-duplicated with -2, -3 and so on until the composed URL is free within your workspace. A slug supplied when a page is created is ignored; the derived one wins. This is also why an AI client or importer cannot choose a page’s slug at creation time, and it is worth knowing before you author a page that links to it.
Change a slug afterwards from the page’s own settings — and do it before anything links to the page, so no other page has to be revisited.
What a mismatch actually costs
The rule that a page’s file location equals page type path + folder path + slug is enforced in code, not by convention:
- On the repository side, a page’s folder path is derived from the markdown file’s directory relative to
src/<page type path>/. A file that disagrees with its record is a hard failure, not a warning. - The stored folder path is constrained to lowercase segments with no leading or trailing slash —
^[a-z0-9-]+(/[a-z0-9-]+)*$— so a path that is not already slug-shaped cannot be written at all. - Composed URLs are unique per workspace, enforced by the database.
A page whose menu placement and stored path disagree therefore looks fine right up until the next documentation-menu save, when the recompute notices and stages a URL move for it. That move ripples: a new row in the paths table, a redirect from the old URL, a new sitemap entry, a break in analytics continuity for the old address, new breadcrumbs, a new position in the previous/next chain — and it can collide with a URL another page already owns, which rejects the whole menu save.
This is why the invariant is worth respecting rather than working around. It is checkable, and the check runs whether or not you were thinking about it.
Renaming or moving a folder
Every page beneath the folder gets a new URL. What happens next depends on one thing: whether you can publish.
flowchart TD
A["Old folder ancestry"] --> C["Folder path change<br/>computed per affected page"]
B["New folder ancestry"] --> C
C --> D{"Can you publish<br/>this menu?"}
D -- "yes" --> E["New path committed<br/>and deployed now"]
D -- "no" --> F["New path staged as 'next'<br/>lands at the page's next publish"]
E --> G["Old URL kept as a permanent redirect"]
F --> G
The branch is the thing prose keeps burying: the same action takes effect at two different moments depending on who performed it. With publishing rights, the moved published pages are committed and deployed straight away and the new URLs are live within minutes. Without them, each page’s new URL is staged and lands the next time that page is published — so a writer can reorganize the navigation without shipping a URL change nobody reviewed. Which roles carry which rights is in Roles and Permissions.
A staged move is visible: open any affected page’s settings and you will see both its live URL and the pending one.
flowchart TD
A["Rename a folder in the Documentation tree"] --> B{"Do you hold publishing rights?"}
B -- Yes --> C["Published pages move immediately"]
B -- No --> D["The move is staged"]
D --> E["Page settings show the live URL<br/>alongside the pending one"]
E --> F["Applied at the next publish"]
Old URLs are not lost
When a page’s URL changes, its previous URL is kept and becomes a permanent redirect. Readers with the old link, and search engines with the old address, land on the new page. You do not create the redirect and you cannot forget to. What Leed creates for you automatically, and what you can add by hand, is at Aliases and Redirects.
Why a move was rejected
A menu save that would produce an illegal URL is rejected whole — no page is moved and the menu is not saved.
| Cause | Status | Exact message | What to change |
|---|---|---|---|
| The set’s navigation is locked | 403 | Cannot change navigation: the '<page type>' page type's navigation is locked. An Administrator or Content Publisher can uncheck Navigation Menu Locked in Settings → Page Types. | Uncheck Navigation Menu Locked on the page type, or leave the URLs alone |
| A page would land exactly on another page type’s root | 409 | Cannot move page: the path '<path>' is the root path of the '<page type>' page type | Rename the folder, or file the page one level deeper. Overlapping another set’s namespace is allowed — landing exactly on its root is not |
| The target URL is already owned by another page | 409 | Cannot move page: the path '<path>' is already in use by another page | Change this page’s slug, or rename the folder so the composed path differs |
If the move is rejected because navigation is locked, the checkbox is on the page type: see Configuring a Page Type.
Two placements to avoid
Do not park a page at the set root. A page with an empty slug composes to /{page type path}/, and URLs are unique per workspace — so whatever already answers at that address, whether a landing page built from your own templates or another set’s index, collides with it. If you want a landing page for the set, give it a real slug and point the set’s Starting Page at it.
Do not give two sibling folders names that slugify the same. Pages & Editing and Pages and Editing both become pages-and-editing. Nothing warns you at the moment you type the second name; you find out when the first page you move into it collides with a URL that already exists.
A worked reorganization
Suppose Getting Started should have been Start Here.
- Rename the folder. Double-click it in the set’s tree, type
Start Here, and save the menu. Every page beneath it now targets/docs/start-here/…. - Check one page. Open a page from that folder and look at its settings. If you can publish, its URL already reads
/docs/start-here/…. If not, you see the live/docs/getting-started/…URL and the staged/docs/start-here/…beside it. - Publish. A staged move lands when the page publishes. Publishing the whole set at once is the sane way to do it — see Publishing a Documentation Set.
- Verify the redirect. Once the site has rebuilt, request the old URL. It should answer with a permanent redirect to the new one. If it does not, the page has not published yet — the redirect is written from the page’s own record, not from the menu.
The single mistake to avoid here is doing this after a set has inbound links from elsewhere on the web. The redirects work, but every one of them is a hop you are paying for forever. Get folder names right before launch; that is the whole reason this page exists.