diff --git a/docs/messages/en.json b/docs/messages/en.json index 3c4b91e6..50856bee 100644 --- a/docs/messages/en.json +++ b/docs/messages/en.json @@ -6,6 +6,7 @@ "category_router": "Router", "category_deploy": "Deploy", "category_tutorials": "Tutorials", + "category_advanced": "Advanced", "category_team": "Team", "algolia_placeholder": "Search docs", "algolia_buttonText": "Search", diff --git a/docs/messages/ja.json b/docs/messages/ja.json index 6252f48a..6819b1c2 100644 --- a/docs/messages/ja.json +++ b/docs/messages/ja.json @@ -6,6 +6,7 @@ "category_router": "ルーター", "category_deploy": "デプロイ", "category_tutorials": "チュートリアル", + "category_advanced": "高度な", "category_team": "チーム", "algolia_placeholder": "ドキュメントを検索", "algolia_buttonText": "検索", diff --git a/docs/package.json b/docs/package.json index 6793424d..2a01c4bd 100644 --- a/docs/package.json +++ b/docs/package.json @@ -10,6 +10,7 @@ "start": "react-server start" }, "dependencies": { + "@docsearch/css": "^3.6.0", "@docsearch/react": "3", "@lazarv/react-server": "workspace:^", "@opentelemetry/api": "^1.9.0", @@ -24,10 +25,13 @@ "@uidotdev/usehooks": "^2.4.1", "algoliasearch": "^4.24.0", "highlight.js": "^11.9.0", + "katex": "^0.16.38", "lucide-react": "^0.408.0", "rehype-highlight": "^7.0.0", + "rehype-katex": "^7.0.1", "rehype-mdx-code-props": "^3.0.1", "remark-gfm": "^4.0.0", + "remark-math": "^6.0.0", "three": "^0.183.1", "vite-plugin-svgr": "^4.5.0" }, diff --git a/docs/react-server.config.mjs b/docs/react-server.config.mjs index 2f655b29..d0ded934 100644 --- a/docs/react-server.config.mjs +++ b/docs/react-server.config.mjs @@ -1,6 +1,8 @@ import rehypeHighlight from "rehype-highlight"; +import rehypeKatex from "rehype-katex"; import rehypeMdxCodeProps from "rehype-mdx-code-props"; import remarkGfm from "remark-gfm"; +import remarkMath from "remark-math"; export default { root: "src/pages", @@ -12,8 +14,12 @@ export default { }, ], mdx: { - remarkPlugins: [remarkGfm], - rehypePlugins: [[rehypeHighlight, { detect: true }], rehypeMdxCodeProps], + remarkPlugins: [remarkGfm, remarkMath], + rehypePlugins: [ + [rehypeHighlight, { detect: true }], + rehypeMdxCodeProps, + rehypeKatex, + ], components: "./src/mdx-components.jsx", }, prerender: false, @@ -25,6 +31,7 @@ export default { return [ ...paths.map(({ path }) => ({ path: path.replace(/^\/en/, ""), + filename: path === "/" ? "index.html" : `${path.slice(1)}.html`, rsc: false, })), // Markdown versions of all docs pages for AI usage diff --git a/docs/src/components/PageMeta.jsx b/docs/src/components/PageMeta.jsx new file mode 100644 index 00000000..33a0891f --- /dev/null +++ b/docs/src/components/PageMeta.jsx @@ -0,0 +1,34 @@ +export default function PageMeta({ date, author, github, lang }) { + if (!date && !author && !github) return null; + + return ( +
+ {author || github}
+
+ ) : author ? (
+ {author}
+ ) : null}
+ {date ? (
+
+ ) : null}
+ + {children} +
+ ); +} diff --git a/docs/src/pages.mjs b/docs/src/pages.mjs index 86fc074b..a50fe13b 100644 --- a/docs/src/pages.mjs +++ b/docs/src/pages.mjs @@ -7,6 +7,7 @@ const frontmatterLoaders = import.meta.glob( { import: "frontmatter" } ); const loaders = import.meta.glob("./pages/*/\\(pages\\)/**/*.{md,mdx}"); +const indexPages = import.meta.glob("./pages/*/*.\\(index\\).{md,mdx}"); export const pages = await Promise.all( Object.entries(frontmatterLoaders).map(async ([key, load]) => [ key, @@ -21,6 +22,7 @@ export const categories = [ "Router", "Deploy", "Tutorials", + "Advanced", "Team", ]; @@ -112,3 +114,25 @@ export function getPages(pathname, lang) { export function hasCategory(category) { return categories?.find((c) => c.toLowerCase() === category?.toLowerCase()); } + +export function hasCategoryIndex(category, lang) { + return ( + Object.keys(indexPages).some( + (key) => + key === `./pages/${lang}/${category.toLowerCase()}.(index).md` || + key === `./pages/${lang}/${category.toLowerCase()}.(index).mdx` + ) || + pages.some( + ([, { frontmatter }]) => frontmatter?.slug === category.toLowerCase() + ) + ); +} + +export function getPageFrontmatter(pathname, lang) { + const allPages = getPages(pathname, lang); + for (const { pages: categoryPages } of allPages) { + const page = categoryPages.find((p) => p.isActive); + if (page) return page.frontmatter; + } + return null; +} diff --git a/docs/src/pages/(root).layout.jsx b/docs/src/pages/(root).layout.jsx index 21372086..81f479d1 100644 --- a/docs/src/pages/(root).layout.jsx +++ b/docs/src/pages/(root).layout.jsx @@ -1,14 +1,17 @@ +import "@docsearch/css"; import "highlight.js/styles/github-dark-dimmed.css"; +import "katex/dist/katex.min.css"; import "./global.css"; import { cookie, usePathname } from "@lazarv/react-server"; import { useMatch } from "@lazarv/react-server/router"; import EditPage from "../components/EditPage.jsx"; +import PageMeta from "../components/PageMeta.jsx"; import ViewMarkdown from "../components/ViewMarkdown.jsx"; import { useLanguage, m } from "../i18n.mjs"; import { defaultLanguage, defaultLanguageRE, languages } from "../const.mjs"; -import { categories } from "../pages.mjs"; +import { categories, getPageFrontmatter } from "../pages.mjs"; const lowerCaseCategories = categories.map((category) => category.trim().toLowerCase() @@ -36,6 +39,7 @@ export default function Layout({ new RegExp(`^/(${defaultLanguage}|${lang})`), "" ); + const frontmatter = getPageFrontmatter(pathname, lang); return (