-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Only 404 lint unique files #15452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Only 404 lint unique files #15452
Changes from all commits
b029a23
c665eb9
680154b
406463a
424c688
3c9fa26
4035523
51a3d4d
9e8f7d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| import {NextResponse} from 'next/server'; | ||
|
|
||
| import {apiCategories} from 'sentry-docs/build/resolveOpenAPI'; | ||
| import {getDevDocsFrontMatter, getDocsFrontMatter} from 'sentry-docs/frontmatter'; | ||
| import {isDeveloperDocs} from 'sentry-docs/isDeveloperDocs'; | ||
|
|
||
| /** | ||
| * API endpoint that returns a mapping of slugs to their source file paths. | ||
| * This is used by the 404 link checker to deduplicate pages that share the same source. | ||
| */ | ||
| export async function GET() { | ||
| const docs = await (isDeveloperDocs ? getDevDocsFrontMatter() : getDocsFrontMatter()); | ||
|
|
||
| // For non-developer docs, add API-generated pages (they have undefined sourcePath) | ||
| if (!isDeveloperDocs) { | ||
| const categories = await apiCategories(); | ||
| categories.forEach(category => { | ||
| docs.push({ | ||
| title: category.name, | ||
| slug: `api/${category.slug}`, | ||
| sourcePath: undefined, | ||
| }); | ||
|
|
||
| category.apis.forEach(api => { | ||
| docs.push({ | ||
| title: api.name, | ||
| slug: `api/${category.slug}/${api.slug}`, | ||
| sourcePath: undefined, | ||
| }); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| const sourceMap: Record<string, string | null> = {}; | ||
|
|
||
| for (const doc of docs) { | ||
| // Normalize slug (remove leading and trailing slashes to match main.ts trimSlashes) | ||
| const slug = doc.slug.replace(/(^\/|\/$)/g, ''); | ||
| // sourcePath will be null for API-generated pages | ||
| sourceMap[slug] = doc.sourcePath ?? null; | ||
| } | ||
|
|
||
| return NextResponse.json(sourceMap); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| import type {MetadataRoute} from 'next'; | ||
|
|
||
| import {getDevDocsFrontMatter, getDocsFrontMatter} from 'sentry-docs/frontmatter'; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: Sitemap excludes critical API documentation.The sitemap changed its import from |
||
| import {isDeveloperDocs} from 'sentry-docs/isDeveloperDocs'; | ||
| import {getDevDocsFrontMatter, getDocsFrontMatter} from 'sentry-docs/mdx'; | ||
|
|
||
| export default async function sitemap(): Promise<MetadataRoute.Sitemap> { | ||
| if (isDeveloperDocs) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| # 404 Link Checker | ||
|
|
||
| This script checks all documentation pages for broken internal links (404s). | ||
|
|
||
| ## Usage | ||
|
|
||
| ```bash | ||
| # Basic usage (with deduplication - recommended) | ||
| bun ./scripts/lint-404s/main.ts | ||
|
|
||
| # Show progress for each page | ||
| bun ./scripts/lint-404s/main.ts --progress | ||
|
|
||
| # Skip deduplication and check all pages (for debugging) | ||
| bun ./scripts/lint-404s/main.ts --skip-deduplication | ||
|
|
||
| # Filter to a specific path | ||
| bun ./scripts/lint-404s/main.ts --path platforms/javascript | ||
| ``` | ||
|
|
||
| ## Deduplication | ||
|
|
||
| By default, the checker **deduplicates common files** to improve performance. | ||
|
|
||
| ### Why? | ||
|
|
||
| The Sentry docs use a "common" file system where documentation is shared across multiple platforms. For example: | ||
|
|
||
| - `/platforms/apple/common/configuration/index.mdx` is rendered as: | ||
| - `/platforms/apple/guides/ios/configuration/` | ||
| - `/platforms/apple/guides/macos/configuration/` | ||
| - `/platforms/apple/guides/watchos/configuration/` | ||
| - ... and many more | ||
|
|
||
| Without deduplication, the checker would fetch and test the same content dozens of times, which: | ||
|
|
||
| - Takes much longer to run | ||
| - Wastes CI resources | ||
| - Provides no additional value (the content is identical) | ||
|
|
||
| ### How it works | ||
|
|
||
| 1. The checker fetches a source map from `/api/source-map` that maps each slug to its source file | ||
| 2. It tracks which source files have been checked | ||
| 3. For common files, it only checks the first instance | ||
| 4. **API-generated pages** are always checked (they have no source file) | ||
|
|
||
| This typically reduces the number of pages checked from **~9,000 to ~2,500**, a **72% reduction**. | ||
|
|
||
| ### When to use `--skip-deduplication` | ||
|
|
||
| Use this flag to skip deduplication and verify that all rendered pages work correctly, even if they share the same source. This is rarely necessary but can help debug issues with: | ||
|
|
||
| - Path routing | ||
| - Platform-specific rendering bugs | ||
| - Edge cases in the build system | ||
|
|
||
| ## Ignore List | ||
|
|
||
| The `ignore-list.txt` file contains paths that should be skipped during checking. Add paths here (one per line) if they're known to be inaccessible or are special cases. | ||
|
|
||
| ## Exit Codes | ||
|
|
||
| - `0` - No 404s found | ||
| - `1` - 404s were detected |
Uh oh!
There was an error while loading. Please reload this page.