Harden last-updated dates: CI guard, SEO metadata, View history link (#904)

This commit is contained in:
Brandon Hopkins
2026-08-05 13:06:30 -07:00
committed by GitHub
parent 8aa22ac4ce
commit a51653a93d
6 changed files with 95 additions and 34 deletions

View File

@@ -1,7 +1,9 @@
#!/usr/bin/env node
/**
* Generates src/lib/edit-on-github-routes.js by scanning src/pages for index.mdx.
* Used by Layout.jsx so "Edit on GitHub" links point to .../index.mdx for those routes.
* Generates src/lib/edit-on-github-routes.js by scanning src/pages for .mdx files.
* Used by Layout.jsx so "Edit on GitHub" links point to .../index.mdx for index
* routes, and so GitHub links render only on routes backed by a real MDX file
* (e.g. not on the prerendered 404/500 pages, where pathname is /_error).
* Run automatically with dev and build.
*/
@@ -14,29 +16,37 @@ const ROOT = path.join(__dirname, '..')
const PAGES_DIR = path.join(ROOT, 'src/pages')
const OUT_PATH = path.join(ROOT, 'src/lib/edit-on-github-routes.js')
function findIndexMdxRoutes(dir, basePath = '') {
function findMdxRoutes(dir, basePath = '') {
const entries = fs.readdirSync(dir, { withFileTypes: true })
const routes = []
const indexRoutes = []
const allRoutes = []
for (const e of entries) {
const rel = basePath ? `${basePath}/${e.name}` : e.name
if (e.isDirectory()) {
routes.push(...findIndexMdxRoutes(path.join(dir, e.name), rel))
const nested = findMdxRoutes(path.join(dir, e.name), rel)
indexRoutes.push(...nested.indexRoutes)
allRoutes.push(...nested.allRoutes)
} else if (e.name === 'index.mdx') {
routes.push('/' + basePath)
indexRoutes.push('/' + basePath)
allRoutes.push('/' + basePath)
} else if (e.name.endsWith('.mdx')) {
allRoutes.push('/' + rel.replace(/\.mdx$/, ''))
}
}
return routes
return { indexRoutes, allRoutes }
}
const routes = findIndexMdxRoutes(PAGES_DIR)
.filter((r) => r !== '') // ignore root index if any
.sort()
const { indexRoutes, allRoutes } = findMdxRoutes(PAGES_DIR)
const routes = indexRoutes.filter((r) => r !== '/').sort() // ignore root index if any
const mdxRoutes = allRoutes.filter((r) => r !== '/').sort()
const content = `// Auto-generated by scripts/generate-github-routes.mjs do not edit
/** Pathnames served by src/pages/.../index.mdx (Edit on GitHub must link to /index.mdx). */
export const EDIT_ON_GITHUB_INDEX_ROUTES = new Set(${JSON.stringify(routes)});
/** Every pathname backed by an .mdx file under src/pages. GitHub links are hidden elsewhere. */
export const MDX_PAGE_ROUTES = new Set(${JSON.stringify(mdxRoutes)});
`
fs.mkdirSync(path.dirname(OUT_PATH), { recursive: true })
fs.writeFileSync(OUT_PATH, content, 'utf8')
console.log('Generated', OUT_PATH, 'with', routes.length, 'index routes')
console.log('Generated', OUT_PATH, 'with', routes.length, 'index routes,', mdxRoutes.length, 'mdx routes')

View File

@@ -60,3 +60,19 @@ export const LAST_UPDATED_BY_ROUTE = ${JSON.stringify(map, null, 2)};
fs.mkdirSync(path.dirname(OUT_PATH), { recursive: true })
fs.writeFileSync(OUT_PATH, content, 'utf8')
console.log('Generated', OUT_PATH, 'with', Object.keys(map).length, 'dated routes')
if (Object.keys(map).length === 0) {
const msg =
'[last-updated] no routes received a date, git history is unavailable or the clone is shallow'
// Hard-fail only where full history is guaranteed (the GitHub workflow
// checks out with fetch-depth: 0). Other CI environments like Vercel
// shallow-clone by design, so there a missing map is expected: warn and
// ship pages without "Updated" dates instead of breaking the deploy.
if (process.env.GITHUB_ACTIONS) {
console.error(
`${msg}. Failing the build: the workflow checks out with fetch-depth: 0, so an empty map means something is broken.`
)
process.exit(1)
}
console.warn(`${msg}. Pages will render without an "Updated" date.`)
}