Skip to content

feat(routing): G E flip trailingSlash → always, cascade canonical URL form#16

Merged
blackbrowed-labs merged 1 commit into
devfrom
claude/exciting-dirac-b2eeea
May 12, 2026
Merged

feat(routing): G E flip trailingSlash → always, cascade canonical URL form#16
blackbrowed-labs merged 1 commit into
devfrom
claude/exciting-dirac-b2eeea

Conversation

@larsweiser
Copy link
Copy Markdown
Collaborator

Summary

Eliminates the one-hop /ueber/ueber/ 307 between Astro's canonical URLs and the URL Cloudflare Workers Static Assets serves natively. Closes backlog #1 (Phase E, G6).

  • Astro trailingSlash: 'never''always'; canonicalise() in src/lib/i18n.ts inverts to keep/add slash; counterparts map keys+values all slash-terminal with asymmetric '/' ↔ '/en/' root preserved.
  • Cascade through both nav components (SiteHeader 5 hrefs + SiteFooter 5 hrefs, with *Active reducers simplified), eight page templates' breadcrumb + product-card anchors, and two markdown editorial contact-page disclosure links.
  • getLocaleFromPath drops the now-dead canonical === '/en' first condition (canonicalise now guarantees trailing slash).

14 files / 49 ins / 45 del.

Verification

  • npm run check — 0 errors, 0 warnings.
  • npm run build — clean.
  • dist/-grep proves zero slash-less internal hrefs survive (filtered for assets).
  • ✅ Canonical + hreflang URLs in built HTML all end in / (including /en/ for EN root — Astro 6 auto-normalises Astro.url.pathname to the slash-terminal form, so no BaseLayout.astro source change needed).
  • ✅ Two-stage integration review (spec-compliance + code-quality, parallel subagents) cleared — non-blocking forward-looking notes only (backlog chore(docs): document staging dispatch workflow in TECH_STACK §7 #24 + Rollout — TECH_STACK §7 staging dispatch docs #25).
  • ✅ Cloudflare Redirect Rules audit — existing "Redirect from WWW to root" rule is hostname-level, not path-level; no compounding regression. Artefact at plans/active/pass-2/g-e/cf-redirect-rules.md.

Test plan

  • Staging deploys cleanly from this PR's merge into dev.
  • curl -I https://dev.blackbrowedlabs.com/ueber/ returns 200, not 307.
  • curl -I https://dev.blackbrowedlabs.com/en/about/ returns 200, not 307.
  • curl -I https://dev.blackbrowedlabs.com/datenschutz/ returns 200.
  • curl -Ls -o /dev/null -w '%{num_redirects}\n' https://dev.blackbrowedlabs.com/ueber/ returns 0.
  • Language-switcher click on /ueber/, /en/about/, /datenschutz/, /en/privacy/, and one product detail URL — no redirect hop in the browser network tab.
  • One product card click from /produkte/ and /en/products/ lands directly on the slug page with no 307.

Production rollout waits for Phase F's full staging walkthrough (108-state Pass 2 matrix per plans/active/pass-2/plan.md §Phase F.1).

🤖 Generated with Claude Code

… form

Eliminates the one-hop /ueber → /ueber/ 307 at the Cloudflare edge by
making every URL we emit (canonical link, hreflang alternates, nav
hrefs, breadcrumbs, i18n counterpart map, markdown editorial links)
match the trailing-slash form Workers Static Assets serves natively.

Astro config: trailingSlash 'never' → 'always'. canonicalise() in
src/lib/i18n.ts inverts: keeps/adds trailing slash instead of stripping.
counterparts map keys and values gain trailing slashes on both sides;
the '/' ↔ '/en/' asymmetry is canonical, not a bug. getLocaleFromPath
drops the now-dead '=== /en' first condition. Nav component href
constants (SiteHeader homeHref/aboutHref/productsHref/contactHref;
SiteFooter products/about/contact/legal/privacy) cascade with the
*Active reducers simplified accordingly. EN-sibling breadcrumb anchors
(/en, /en/products) and product-detail dynamic template-string hrefs
on both index pages get the trailing slash. Two markdown editorial
contact-page disclosures link to /datenschutz/ and /en/privacy/ for
the same reason — the rendered HTML grep surfaced them.

Verified locally: npm run check 0-error; npm run build clean; dist/-
grep proves zero slash-less internal hrefs survive; canonical and
hreflang URLs in built HTML all end in / (including /en/). Astro 6
auto-normalises Astro.url.pathname to the trailing-slash form when the
flag is set, so BaseLayout's canonical/og:url emitter needs no source
change. Workers Static Assets' default html_handling: "auto-trailing-
slash" keeps external /ueber → /ueber/ redirects working at the edge —
that is the expected behaviour, not the bug we are fixing.

Two-stage integration review (spec-compliance + code-quality, parallel
subagents) cleared the diff with non-blocking forward-looking notes
(plan-template refinement for markdown editorial files; Pass-3
broadening of E.7's asset-filter blacklist).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants