1- ---
2-
31# ADR 0008 — URL structure: MyST flat slugs vs Hugo hierarchical paths
42
5- Date : 2026-05-19
3+ Date: 2026-05-18
64Status: Proposed
75Branch: lb/myst-migration
86
@@ -11,18 +9,23 @@ Branch: lb/myst-migration
119Hugo derives page URLs from the directory structure: ` content/about/governance.md `
1210→ ` /about/governance/ ` . The directory hierarchy IS the URL.
1311
14- MyST derives URLs from the filename only, ignoring the containing directory :
15- ` content/about/governance.md` → `/governance`. Files named `index.md` in
16- subdirectories collide on the slug `index` and are deduplicated as `index-1`,
17- `index-2`, etc. : ` content/about/index.md` → `/index-1`.
12+ MyST's default behaviour derives URLs from the filename only, ignoring the
13+ containing directory: ` content/about/governance.md ` → ` /governance ` . Files
14+ named ` index.md ` in subdirectories collide on the slug ` index ` and are
15+ deduplicated as ` index-1 ` , ` index-2 ` , etc.: ` content/about/index.md ` →
16+ ` /index-1 ` .
1817
19- This behaviour is not user-configurable; URL generation is internal to MyST.
18+ MyST does support directory-based URLs via ` site.options.folders: true ` in
19+ ` myst.yml ` , which maps ` content/about/governance.md ` → ` /about/governance/ ` .
20+ Index files in subdirectories become section landing pages
21+ (` content/about/index.md ` → ` /about/ ` ). This is the documented approach for
22+ preserving nested folder structure.
2023
2124This was surfaced by ` netlify-plugin-checklinks ` during the first Netlify
22- deploy of the PR. The build succeeds; the link checker finds broken internal
25+ deploy of the PR. The build succeeds; the link checker finds 12 broken internal
2326links because content was authored for Hugo-style hierarchical URLs
24- (`/about/governance`, `/contributors/`, etc.) that no longer exist in the
25- MyST output.
27+ (` /about/governance ` , ` /contributors/ ` , etc.) that do not exist under MyST's
28+ default flat-slug output.
2629
2730Affected link types:
2831
@@ -34,48 +37,63 @@ Affected link types:
3437
3538## Options considered
3639
37- 1. **Rename `index.md` to `section.md` + update all internal links to flat URLs**
40+ 1 . ** Enable ` site.options.folders: true ` in ` myst.yml ` **
41+ - Add one line to ` myst.yml ` ; no content changes required.
42+ - MyST generates ` content/about/governance.md ` → ` /about/governance/ ` ,
43+ matching the existing Hugo URL structure.
44+ - ` content/<section>/index.md ` files become section landing pages
45+ (` /contributors/ ` , ` /about/ ` , etc.) — matching Hugo's behaviour exactly.
46+ - Existing ` :link: ` values and inline markdown links in content continue
47+ to resolve correctly without modification.
48+ - Pros: minimal change, follows MyST's documented recommendation, preserves
49+ URL continuity for external links, no SEO disruption.
50+ - Cons: path conflicts arise if both ` <section>.md ` and
51+ ` <section>/index.md ` exist (the file wins; the index gets a deduplicated
52+ slug). No such conflicts exist in the current content tree.
53+
54+ 2 . ** Rename ` index.md ` to ` section.md ` + update all internal links to flat URLs**
3855 - Rename each ` content/<section>/index.md ` to ` content/<section>/<section>.md `
3956 so MyST generates slug ` /<section> ` instead of ` /index-N ` .
4057 - Update all cross-page links in content to use flat URLs (` /governance `
4158 not ` /about/governance ` ).
4259 - Add a Netlify ` _redirects ` file mapping old Hugo URLs to new flat URLs for
4360 external link / bookmark compatibility.
44- - Pros : honest fix, works within MyST's model, flat URLs are simpler.
45- - Cons : URL structure changes permanently; external links to the Hugo site
46- break without redirects; flat URLs lose the section context for users
47- reading the URL.
61+ - Pros: flat URLs are shorter; works without ` folders ` option.
62+ - Cons: large mechanical content churn; URL structure changes permanently;
63+ external links to the Hugo site break without redirects; flat URLs lose
64+ section context; SEO impact from changed URLs persists until redirects
65+ are indexed.
4866
49- 2 . **Netlify `_redirects` shim (keep Hugo-style links, redirect to flat URLs)**
67+ 3 . ** Netlify ` _redirects ` shim (keep Hugo-style links, redirect to flat URLs)**
5068 - Keep content links as-is; add a ` _redirects ` file that maps every
5169 hierarchical Hugo URL to the corresponding flat MyST slug.
5270 - Pros: no content changes; external links preserved.
5371 - Cons: fragile — ` index-N ` numbering shifts if toc order changes;
5472 maintenance burden every time a page is added; masks the underlying issue.
5573
56- 3 . **Disable `netlify-plugin-checklinks` failure / warn-only**
74+ 4 . ** Disable ` netlify-plugin-checklinks ` failure / warn-only**
5775 - Configure or remove the plugin so broken links produce warnings, not a
5876 build failure. Defers URL fix to a follow-up issue.
5977 - Pros: unblocks the PR immediately.
60- - Cons : leaves broken links in the deployed site; removes the safety net.
61-
62- 4. **File a MyST feature request for directory-based URL generation**
63- - Request that MyST support an option to derive page URLs from the directory
64- path rather than the filename alone.
65- - Pros : correct fix at the right layer; no workarounds needed.
66- - Cons : timeline unknown; blocks the PR on upstream response.
78+ - Cons: leaves broken links in the deployed site; removes the link-integrity
79+ safety net established by ADR 0007.
6780
6881## Decision
6982
7083_ Pending team discussion._
7184
85+ Recommendation: Option 1 (` site.options.folders: true ` ). It is the single-line
86+ fix that follows MyST's documented design for folder-based URLs, preserves the
87+ existing URL structure without any content edits, and eliminates the 12 broken
88+ internal links immediately.
89+
7290## Consequences
7391
74- - Until resolved, `netlify-plugin-checklinks` will fail on every Netlify deploy.
75- - Option 1 (rename + redirects) is the most honest long-term fix and aligns with
76- MyST's design; it should be the default choice unless a MyST fix lands quickly.
77- - This ADR should be inserted before the Phase 3 commits in the final commit
78- history, since the URL structure decision affects how shortcode links are
79- written .
80- - If option 1 is chosen, Phase 3 (shortcode conversion) commits will need a
81- follow-up fixup to update card `:link:` values and inline markdown links.
92+ - Option 1 requires one ` myst.yml ` change and no content edits. The 12 broken
93+ internal links are resolved without touching any ` .md ` files.
94+ - External links from the Hugo site ( ` /about/governance/ ` , ` /contributors/ ` ,
95+ etc.) continue to work unchanged — no redirects needed.
96+ - If Option 1 is chosen, Phase 3 card ` :link: ` values and inline markdown
97+ links require no fixup .
98+ - Until resolved, ` netlify-plugin-checklinks ` will fail on every Netlify deploy
99+ with 12 broken internal links.
0 commit comments