Repository navigation
chore: Lint internal path literals in application code - #19812
coolguyzone wants to merge 3 commits into
Conversation
The trailing-slash linter from #19666 only reads docs/, includes/ and platform-includes/, so internal paths written in components were never checked. A component renders on many pages, which makes each one cost more than a slash-less link in a single doc. An audit of 300 rendered pages found seven: src/components/featureInfo.tsx 6 (renders on platform pages) src/components/apiPage/index.tsx 1 src/components/specMeta.tsx 1 (develop-docs) All are fixed here. Five just needed the slash; /product/tracing/ 308s even with one, since tracing concepts moved to /concepts/key-terms/ tracing/, so that link gets the real destination. Adds scripts/lint-code-link-literals.ts and `pnpm lint:code-links`, plus a step on the existing non-blocking workflow, which now also triggers on src/ and app/. Report-only, with no --fix, because a slash-prefixed literal in code is not reliably a link. Two of the ten the first pass turned up must keep their current form: - app/platform-redirect/page.tsx compares a pathname with the trailing slash stripped. Adding one would break the comparison, so the line carries a `trailing-slash-ignore` marker explaining why. - internalLinkTracking.ts documents its own normalization in a JSDoc comment ("`/product/logs` and `/product/logs/` both become `/product/logs/`"). Rather than mark that, the linter skips comment lines: a path in a comment is never a rendered link, and reporting it would invite someone to "fix" the prose. 18 unit tests cover the exemptions, the comment handling and the marker. The <a>-vs-<Link> eslint warnings in the touched components are pre-existing -- 8 on master, 8 after this change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
The plan checks that help links still open their target pages. It also checks client errors on those pages. An issue escalates when target-page traffic falls or client errors rise. The tracing help link now opens a different page. Watch that new page. Services: Mention PlanWhat changedFeatureInfo learn-more links now include a trailing slash. Readers should reach those pages without a slash redirect. The tracing learn-more link now opens RiskA bad href sends readers to a missing page. FeatureInfo renders on many quick-start pages. One bad link then repeats across those pages. The tracing remap can strand readers if Intended effectThe new behavior is that those links open the slash-terminated pages. It is not the absence of errors. Client pageloads record the URL after a slash redirect. Sentry does not show the 308. Treat steady sampled pageloads on the destination paths as the reachable success signal. Absent: those destination counts fall while other docs traffic holds. Absent for the remap:
Regression watchThis diff can break FeatureInfo, ApiPage, or SpecMeta renders. It can also 404 the remapped tracing page. Client errors are the symptom on-call would see. Watch sibling FeatureInfo targets the same way. A drop on
Not observableNext.js trailing-slash 308 responses do not appear in Sentry spans. A search for |
Reported by Sentry Bot on #19812, and correct. Comments were detected with a per-line pattern anchored on `//`, `/*` or `*`. A JSX comment opens with `{` first, so a quoted path inside one was reported: {/* was <Link to="/product/logs"> before */} -> flagged Adding `{/*` to the pattern would not have been enough. JSX comments are routinely written over several lines, and the inner lines look like ordinary code: {/* <Link to="/product/metrics">metrics</Link> -> flagged */} So comments are now stripped with block state carried across lines, rather than matched per line. That also fixes trailing comments on a line of code, which the old pattern missed entirely since the line did not start with a comment. The stripper leaves a `//` preceded by `:` alone, so a URL scheme in a string is not mistaken for a comment start -- otherwise `const u = "https://x", p = "/one/two"` would have dropped the real path after it and silently under-reported. The bot's example used an unquoted path, which the literal pattern would not have matched anyway; the underlying issue is real for quoted ones. Its suggested symptom ("convert to <CodeLink />") does not match this linter, which only ever proposes a trailing slash. Nine behaviors covered by tests, including that flagging resumes after a block closes and that code before an opening `/*` on the same line is still checked. Still clean against the repo. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`stripComments` searched for `//` without tracking quote state, so a
protocol-relative check like `src.startsWith('//')` -- which `config/images.ts`
and `imageLightbox/index.tsx` both use -- truncated the line. Any path literal
written after it on the same line went unreported.
Nothing is missed on this branch today (the linter is still clean, and the five
non-test lines that truncate have no path after the cut), but the gap is silent
by nature: it only ever produces a false negative.
Scans character by character instead, tracking quote and block state, which
also fixes `/*` inside a string being read as a block-comment opener.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
DESCRIBE YOUR PR
The trailing-slash linter from #19666 only reads
docs/,includes/andplatform-includes/— so internal paths written in components were never checked. A component renders on many pages, which makes a slash-less path there cost considerably more than one in a single doc.An audit of 300 rendered pages against production turned up seven:
src/components/featureInfo.tsxsrc/components/apiPage/index.tsx<SmartLink to="/api/auth">src/components/specMeta.tsxAll fixed here. Five just needed the slash.
/product/tracing/308s even with one — tracing concepts moved to/concepts/key-terms/tracing/— so that link gets the real destination rather than a slash.New linter:
pnpm lint:code-linksAdded as a step on the existing non-blocking trailing-slash workflow, which now also triggers on
src/andapp/.Report-only, with no
--fix— deliberately. A slash-prefixed literal in code is not reliably a link, and two of the ten the first pass found must keep their current form:app/platform-redirect/page.tsxcompares a pathname with the trailing slash stripped:Adding a slash would break the comparison. The line carries a
trailing-slash-ignoremarker explaining why.src/internalLinkTracking.tsdocuments its own normalization in a JSDoc comment: "/product/logsand/product/logs/both become/product/logs/". Rather than mark that, the linter skips comment lines — a path in a comment is never a rendered link, and reporting it would invite someone to "fix" prose that is deliberately showing both forms.An auto-fixer would have corrupted both. That's the reason this one reports instead.
Verification
pnpm lint:code-linksis clean on this branch<a>-vs-<Link>eslint warnings in the touched components are pre-existing: 8 on master, 8 after this changeIS YOUR CHANGE URGENT?
Help us prioritize incoming PRs by letting us know when the change needs to go live.
Select exactly one option. For deadlines, replace
YYYY-MM-DDwith the due date. You can update this information later by editing the PR description.SLA
Thanks in advance for your help!
PRE-MERGE CHECKLIST
Make sure you've checked the following before merging your changes:
🤖 Generated with Claude Code