fix(web): Top-Level Pages cards led nowhere, and /privacy was not a real page - #114
Merged
Conversation
… a page The "Top-Level Pages" band advertises eight stable routes, but the cards were plain <h3> text with no anchors -- nothing on that band was clickable. Wrap each card title in a link to its route. /privacy was the worst of the eight. It had no page and no homepage section, so it fell through to [[...slug]], which served the entire homepage (82KB, byte-identical to /openspec, /credential-sharing, and /hire-us) and then scrolled to the card that merely described the page that did not exist. Give it a real page covering what the site actually does: CrawlProof analytics, the Hire Us form, the CoinPay OAuth session cookie, and the credshare boundary -- ciphertext and salted-hash fingerprints are stored, secret values never reach the server. The cards also reused the ids openspec, credential-sharing, and hire-us, which already name sections further up the same document. Duplicate ids made those scroll targets ambiguous, so the cards are now page-<route>. With that, the scroll list in home-interactivity only needs the three routes [[...slug]] still serves; docs, blog, about, terms, and privacy are real routes and were only ever aiming scrollIntoView at a card. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
vu1nz Security Review0 finding(s) in PR #? No security issues found. |
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.
The bug
The
Top-Level Pagesband on logicsrc.com advertises eight stable routes. Two things were wrong with it.1. Nothing on the band was a link. Each card rendered as plain
<h3>/docs · Docs</h3>text. Confirmed against the running app — zero anchors in the whole band:2.
/privacywas not a page. Four of the eight routes have no page of their own and fall through tosrc/app/[[...slug]]/page.tsx, which re-renders the entire homepage and relies on auseEffectscrollIntoView. Fetched from the dev server before the fix:/privacy/openspec/credential-sharing/hire-us/docs/about/termsThe first four are the same homepage, differing only in
<title>and canonical./openspec,/credential-sharing, and/hire-usat least scroll to real content bands./privacyhas no such section, so it scrolled to the card that only described the page — a dead end. A grep forpersonal data|we collect|cookieon the old/privacyreturned 0.3. Duplicate DOM ids. The cards used
id="openspec",id="credential-sharing", andid="hire-us", which already name sections further up the same document, making those scroll targets ambiguous:The fix
<a href="/{route}">so the band links where it says it links./privacypage. Content is grounded in what the code actually does, not boilerplate: CrawlProof analytics (layout.tsx), the Hire Us form fields (api/hire-us/project-request), theHttpOnly/SameSite=LaxCoinPay session cookie (lib/coinpay.ts), and the credshare boundary —002_credshare.sqlstores ciphertext, sealed per-member DEKs, and salted-hash fingerprints, so secret values never reach the server.page-<route>, removing the id collisions.privacyfromROUTE_META, and trim thehome-interactivityscroll list to the three routes[[...slug]]still serves.docs,blog,about, andtermsare real routes and were only ever aimingscrollIntoViewat a card.Verification
npm test(contract): 71 passed / 5 files.npm run build: succeeds, and/privacyis now emitted as○ /privacy(prerendered static) rather than resolving through the catch-all./privacyis 42KB of its own content with noTop-Level Pagesband, and each of the three ids appears exactly once./privacytest, which previously asserted the homepage band appeared there. Playwright could not run on this machine — Ubuntu 26.04 has no supported browser build and the cached Chromium is missinglibatk-1.0.so.0. All 10 browser tests fail here regardless of this change; only the 2 request-only tests run. I validated every assertion in the new tests statically against the real rendered HTML instead (all 14 pass), but the e2e suite still needs a real run in CI.Left alone deliberately
/openspec,/credential-sharing, and/hire-usstill serve the full homepage plus a scroll. Their content is live, so this is not the reported bug, but it does mean four URLs serve near-identical 82KB documents under four different canonicals. Promoting them to real pages is a larger content migration — worth a follow-up.🤖 Generated with Claude Code