feat(docs): add static generation and search indexes

This commit is contained in:
Maofeng
2026-09-20 16:23:32 +08:00
parent a57fdbe7c6
commit 9635de56e8
19 changed files with 529 additions and 169 deletions
+32 -24
View File
@@ -1,3 +1,5 @@
import { lazy } from "react"
import {
defaultDocLocale,
docLocales,
@@ -12,23 +14,17 @@ import {
} from "./types"
import { trans, type Translation } from "../lib/locale"
type DocModule = {
type DocContentModule = {
default: React.ComponentType<{ components?: MdxComponents }>
frontmatter: Record<string, unknown>
}
type LocalizedText = Translation<string>
type PackageDefinition = {
key: string
label: string
description: LocalizedText
description: Translation<string>
}
type ParsedDocPage = DocPage & {
packageKey: string
searchText: string
}
type ParsedDocPage = DocPage & { packageKey: string }
const packageDefinitions: readonly PackageDefinition[] = [
{
@@ -81,18 +77,23 @@ const packageDefinitions: readonly PackageDefinition[] = [
},
]
const docModules = import.meta.glob<DocModule>(
const docModuleLoaders = import.meta.glob<DocContentModule>(
"../../../packages/*/docs/*/**/*.mdx",
{ eager: true }
{ eager: false }
)
const docSources = import.meta.glob<string>(
const docFrontmatter = import.meta.glob<Record<string, unknown>>(
"../../../packages/*/docs/*/**/*.mdx",
{ eager: true, import: "default", query: "?docs-search-raw" }
{ eager: true, import: "frontmatter" }
)
const parsedPages = Object.entries(docModules).map(([path, module]) =>
parseDocPage(path, module, docSources[path] ?? "")
const parsedPages = Object.entries(docFrontmatter).map(
([path, frontmatter]) => {
const load = docModuleLoaders[path]
if (!load) throw new Error(`Missing documentation module for "${path}".`)
return parseDocPage(path, frontmatter, lazy(load))
}
)
const packagesByLocale: Record<DocLocale, readonly DocPackage[]> = {
@@ -147,7 +148,7 @@ export function getLocalizedHref(pathname: string, locale: DocLocale) {
}
export function resolveDocLocale(pathname: string): DocLocale {
const firstSegment = pathname.split("/").filter(Boolean)[0]
const firstSegment = pathname.split("/").find(Boolean)
return isDocLocale(firstSegment) ? firstSegment : defaultDocLocale
}
@@ -193,8 +194,17 @@ export function getDocSectionLabel(section: DocSection, locale: DocLocale) {
return trans(locale, labels[section])
}
export function getDocSearchText(page: DocPage) {
return (page as ParsedDocPage).searchText
export function getStaticDocRoutes() {
return docLocales.flatMap((locale) => {
const home = getDocsHomeHref(locale)
return [
home,
`${home === "/" ? "" : home}/settings`,
...getDocPackages(locale).flatMap((docPackage) =>
docPackage.pages.map((page) => getDocHref(docPackage, page))
),
]
})
}
function createDocPackage(
@@ -205,7 +215,7 @@ function createDocPackage(
.filter(
(page) => page.packageKey === definition.key && page.locale === locale
)
.sort(
.toSorted(
(left, right) =>
docSections.indexOf(left.section) -
docSections.indexOf(right.section) ||
@@ -241,8 +251,8 @@ function createDocPackage(
function parseDocPage(
path: string,
module: DocModule,
source: string
frontmatter: Record<string, unknown>,
Content: DocPage["Content"]
): ParsedDocPage {
const match = path.match(
/\/packages\/([^/]+)\/docs\/([^/]+)\/(overview|guide|advanced|examples)(?:\/([^/]+))?\.mdx$/
@@ -269,14 +279,12 @@ function parseDocPage(
throw new Error(`Documentation file is in the wrong directory: "${path}".`)
}
const frontmatter = module.frontmatter
return {
Content: module.default,
Content,
description: readString(frontmatter, "description"),
locale: localeValue,
order: readNumber(frontmatter, "order"),
packageKey,
searchText: source,
section: sectionValue,
slug: nestedSlug ?? "overview",
title: readString(frontmatter, "title"),