fix(docs): replace linkinator with static broken link checker and fix 134 broken links#8103
Merged
steveruizok merged 5 commits intomainfrom Feb 28, 2026
Merged
Conversation
… 134 broken links Rewrites the check-links script to validate internal links against content.db instead of crawling a running server. Moves the check before next build so broken links fail the build early. Fixes all 134 broken links found across docs content, SDK features, starter kits, and auto-generated API reference pages. Key changes: - checkBrokenLinks.ts: static DB-based checker that extracts links from article content and validates paths/anchors against the DB - getApiMarkdown.ts: render TypeAlias/Interface namespace members on parent page instead of skipping them - utils.ts: namespace members link as anchors on parent page instead of generating broken standalone paths - 25 content files: fix stale /docs/* paths, wrong anchors, renamed examples - package.json: run check-links before next build, remove linkinator
|
The latest updates on your projects. Learn more about Vercel for GitHub.
4 Skipped Deployments
|
Pass --fail to check-links in the build script. Without --fail, broken links are reported as warnings so they never block the dev server.
Collaborator
Author
|
bot lost external link checking, re-steering |
Add a standalone script to check external (HTTP/HTTPS) links across docs content. Refactors extractLinks out of the internal checker so both scripts share link extraction logic. The external checker deduplicates URLs, uses HEAD with GET fallback, 10s timeout, and 10 concurrent requests. Run manually with `yarn check-external-links` from apps/docs.
| const fragment = hashIdx >= 0 ? url.slice(hashIdx + 1).toLowerCase() : null | ||
|
|
||
| // Empty path with fragment = same-page anchor | ||
| if (urlPath === '' && fragment) { |
Contributor
There was a problem hiding this comment.
Not sure we can hit this part at all, we filter out fragment only links in extractInternalLinks.
Add a new empty content.db file to the repository as a placeholder for content database storage. The file is currently an empty blob and contains no data.
| } | ||
|
|
||
| // Framer rewrite prefixes — any path starting with these is served externally | ||
| const FRAMER_PREFIXES = [ |
Contributor
There was a problem hiding this comment.
We already have some logic for getting the framer sitemap here
tldraw/apps/docs/app/sitemap.ts
Line 4 in ce797eb
We could use that instead so that we don't have stale values / have to update this when we add / remove framer pages.
Introduce utils/framer-sitemap.ts to fetch and parse the Framer sitemap into a set of pathnames. Replace the previous inline XML parsing in apps/docs/app/sitemap.ts with fetchFramerPaths(), filter out root and docs-conflicting routes, and append Framer URLs to the docs sitemap. Update apps/docs/scripts/lib/checkBrokenLinks.ts to call fetchFramerPaths() at runtime and remove the hardcoded FRAMER_PREFIXES/isFramerPath logic, preventing maintenance of a stale prefix list and centralizing Framer sitemap handling.
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.
In order to catch broken internal links before they ship (like the ones fixed in #8102), this PR replaces the
linkinator-based HTTP crawler with a static checker that validates links against the content database. The old checker required a running server, couldn't fail the build, and missed most broken links. The new checker runs afterrefresh-everythingand beforenext build, failing early if any broken links are found.Along the way, this fixes all 134 broken internal links found across the docs:
/docs/*paths (should be/sdk-features/*), wrong heading anchors, double-prefixed paths, and renamed example linksTypeAlias/Interfacenamespace members (the// TODO: document thesethat causedT.Validatableetc. to generate broken links)T-Validatableinstead of anchor links likeT#ValidatableThe checker uses a
--failflag to control behavior:yarn check-links --fail(used inbuild) exits non-zero on broken links, whileyarn check-links(used in dev) only warns. This ensures broken links never block the dev server from starting.Additionally, this adds a standalone
yarn check-external-linksscript for manually checking external (HTTP/HTTPS) links across all docs content. It deduplicates URLs, uses HEAD with GET fallback (30s timeout, 10 concurrent requests), and retries transient failures with backoff. A skip list filters out domains that block automated requests (npmjs.com, shadertoy.com). This replaces the external link checking that was previously handled by linkinator but is too slow/flaky for the build pipeline.Also refactors the hardcoded Framer path prefixes into a shared
fetchFramerPaths()utility that fetches the live Framer sitemap. Both the link checker andapp/sitemap.tsnow use this, so the list stays up to date automatically.Fixes a broken external link to the removed
custom-toolbarexample in the v2.1.0 release notes.Change type
improvementTest plan
cd apps/docs && yarn refresh-everything && yarn check-links— should pass with 0 broken links (warnings only)yarn check-links --fail— same result but would exit 1 if any broken links existed[test](/nonexistent)) and runyarn check-links --fail— should exit 1 with the broken link reportedyarn buildfromapps/docs— check-links runs with--failbeforenext buildyarn check-external-links— checks all ~630 unique external URLs, reports broken onesRelease notes
yarn check-external-links)TypeAliasandInterfacemembers within API reference namespaces