Repository navigation
Generate trailing-slash URLs so canonical and sitemap name the served page - #1853
Merged
mrbobbytables merged 1 commit intoOct 23, 2026
Merged
Conversation
… page Netlify serves every page under its trailing-slash URL and 301s the bare form, but the site was generated without trailingSlash set, so every page's rel=canonical and 39 of the 44 sitemap entries named a URL that only ever answers with a redirect. Measured on production 2026-10-23: /resources/metrics 301s to /resources/metrics/, and the page served there declares /resources/metrics as canonical. Set trailingSlash: true in docusaurus.config.js. The sitemap now lists 45 URLs, all in the served form, and each page's canonical is the URL that returns 200. The sitemap ignorePattern becomes /search/** because the plugin matches patterns against the route after the slash is applied, and the test model for that contract now mirrors the setting. End-to-end selectors that pinned exact hrefs gain the slash, and the search spec visits /search/?q= directly, since docusaurus serve drops the query on its redirect where Netlify keeps it. Remit: user-observable defect (every published canonical URL and most sitemap entries redirect instead of resolving). Fixes cncf#1852 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: mrbobbytables <mrbobbytables@users.noreply.github.com>
✅ Deploy Preview for endusers ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1852.
Remit: user-observable defect. Every page's
rel="canonical"and 39 of 44sitemap.xmlentries name a URL that only ever 301s.What was wrong
Netlify serves each page under its trailing-slash URL and redirects the bare form, but
trailingSlashwas unset, so Docusaurus generated the bare form everywhere. Verified on production today:Sitemap: 39 entries without a slash (all 301), 5 with (200).
Change
docusaurus.config.js:trailingSlash: true. Built output now has 45 sitemap entries, all slashed;/resources/metrics/declares itself canonical.ignorePatterns:/searchbecame/search/**. The plugin matches patterns against the route after the slash is applied (@docusaurus/utilscreateMatcheroverroute.path), so the bare pattern let/search/leak into the sitemap on the first build.tests/sitemap-exclusions.test.mjsnow models routes in the served shape and asserts the bare pattern no longer matches.tests/site-config.test.mjs: pinstrailingSlash === truewith the reason.tests/e2e/*: exact-href selectors (href$="/blog/<slug>"etc.) gain the slash;search.spec.jsvisits/search/?q=becausedocusaurus servedrops the query on its slash redirect, where Netlify preserves it (curl -sI 'https://endusers.cncf.io/search?q=foo'->location: /search/?q=foo).No redirects or file layout change: Docusaurus already emitted
<route>/index.htmlfor every page, so existing deep links keep resolving exactly as before; only the generated hrefs, canonical and sitemap change.Validation
npm run buildandnpm run build:productionsucceed withonBrokenLinks: 'throw'intact.npm run test:unit:coverage:checkpasses.npm run test:e2eagainst the production build: 326 passed, 34 skipped (the fixture lane runs only underE2E_COVERAGE=1; its selectors were updated the same way).