fix(frontend): stop SPA fallthrough on /privacy, /cookies, /opt-out #17

Open
PlasticDigits wants to merge 2 commits from issue/12 into main

Fixes #12

Summary

Marketing site (cl8y.com) no longer serves the product SPA for reserved legal-guess paths.

  • Shared path table in src/lib/reservedLegalGuessPaths.ts with unit tests and host-rule alignment checks.
  • public/_redirects + render.yaml: reserved paths are handled before /* → /index.html (404 via /404.html / miss rewrite target).
  • Client defense: no SiteHeader / SiteFooter / product DefaultHead on reserved paths; minimal not-found view.
  • Vite dev/preview middleware returns HTTP 404 for reserved paths (matches production intent for T10).

Acceptance criteria (this repo)

AC Status
AC1 Marketing host/client Done in this PR
AC4 Product routes unchanged Covered by unit + e2e checks
AC5 Query ignored / no open redirect Matcher uses pathname only; e2e asserts no off-origin Location
AC6 No product OG on reserved paths DefaultHead skip + e2e
AC7 Unit tests + docs/skills reservedLegalGuessPaths.test.ts, PROJECT_GUIDE.md, cl8y-host-headers skill
AC8 No privacy notice prose No notice copy added
AC2 DEX Gap — sibling repo code/cl8y-dex-terraclassic (separate PR)
AC3 Bridge Gap — sibling repo code/cl8y-bridge-monorepo (separate PR)

Test plan

  • node --experimental-strip-types --test (all unit suites including new matcher/host-order tests) — 27 passed in implement worktree
  • yarn typecheck, yarn lint, yarn build, yarn test:e2e — not run here (no yarn/installed deps in gate-impl sandbox); CI should run full matrix
  • Post-deploy curl -sI https://cl8y.com/privacy — verify 404 after merge

Notes

Bundle issue #12 also requires matching DEX nginx + App.tsx and bridge main.tsx changes in their own worktrees; this PR is scoped to CL8Y-web only per issue worktree isolation.

Fixes #12 ## Summary Marketing site (`cl8y.com`) no longer serves the product SPA for reserved legal-guess paths. - Shared path table in `src/lib/reservedLegalGuessPaths.ts` with unit tests and host-rule alignment checks. - `public/_redirects` + `render.yaml`: reserved paths are handled **before** `/* → /index.html` (404 via `/404.html` / miss rewrite target). - Client defense: no `SiteHeader` / `SiteFooter` / product `DefaultHead` on reserved paths; minimal not-found view. - Vite dev/preview middleware returns HTTP 404 for reserved paths (matches production intent for T10). ## Acceptance criteria (this repo) | AC | Status | |----|--------| | AC1 Marketing host/client | Done in this PR | | AC4 Product routes unchanged | Covered by unit + e2e checks | | AC5 Query ignored / no open redirect | Matcher uses pathname only; e2e asserts no off-origin `Location` | | AC6 No product OG on reserved paths | `DefaultHead` skip + e2e | | AC7 Unit tests + docs/skills | `reservedLegalGuessPaths.test.ts`, `PROJECT_GUIDE.md`, `cl8y-host-headers` skill | | AC8 No privacy notice prose | No notice copy added | | AC2 DEX | **Gap — sibling repo** `code/cl8y-dex-terraclassic` (separate PR) | | AC3 Bridge | **Gap — sibling repo** `code/cl8y-bridge-monorepo` (separate PR) | ## Test plan - [x] `node --experimental-strip-types --test` (all unit suites including new matcher/host-order tests) — **27 passed** in implement worktree - [ ] `yarn typecheck`, `yarn lint`, `yarn build`, `yarn test:e2e` — not run here (no `yarn`/installed deps in gate-impl sandbox); CI should run full matrix - [ ] Post-deploy `curl -sI https://cl8y.com/privacy` — verify 404 after merge ## Notes Bundle issue #12 also requires matching DEX nginx + `App.tsx` and bridge `main.tsx` changes in their own worktrees; this PR is scoped to **CL8Y-web only** per issue worktree isolation.
Reserved /privacy-style URLs now 404 at the host and client instead of serving the marketing shell with product SEO.

Co-authored-by: Cursor <cursoragent@cursor.com>
Author
Owner

drain skip: no occupying job for rebase/fix-pr/CI-wait; remaining continue

drain skip: no occupying job for rebase/fix-pr/CI-wait; remaining continue
Author
Owner

drain skip: default autoland requires tip ACCEPT (#77)

drain skip: default autoland requires tip ACCEPT (#77)
A once-decoded dot-segment path or a missed host rule could still serve the marketing shell with homepage Open Graph. Match those requests before the SPA fallback and strip the baked-in tags if the client still loads.

Co-authored-by: Cursor <cursoragent@cursor.com>
Some required checks are missing.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin issue/12:issue/12
git switch issue/12
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/CL8Y-web!17
No description provided.