From 8035eabb859d8adde4c972592ecf3a37253829cb Mon Sep 17 00:00:00 2001 From: NtskwK Date: Thu, 26 Mar 2026 09:38:29 +0800 Subject: chore(docs): refactor Mermaid component and clean up imports in documentation pages --- packages/docs/app/components/mermaid.tsx | 2 +- packages/docs/app/docs/page.tsx | 16 ++++++---------- packages/docs/app/routes/home.tsx | 10 +++++----- 3 files changed, 12 insertions(+), 16 deletions(-) (limited to 'packages/docs/app') diff --git a/packages/docs/app/components/mermaid.tsx b/packages/docs/app/components/mermaid.tsx index 2df47cc..85ab342 100644 --- a/packages/docs/app/components/mermaid.tsx +++ b/packages/docs/app/components/mermaid.tsx @@ -17,7 +17,7 @@ export function Mermaid({ chart }: { chart: string }) { nodes: [ref.current], }); } - }, [chart]); + }, []); return (
diff --git a/packages/docs/app/docs/page.tsx b/packages/docs/app/docs/page.tsx index 6ff6b4a..5bddb8d 100644 --- a/packages/docs/app/docs/page.tsx +++ b/packages/docs/app/docs/page.tsx @@ -3,12 +3,7 @@ import { useFumadocsLoader } from "fumadocs-core/source/client"; import { Card, Cards } from "fumadocs-ui/components/card"; import { DocsLayout } from "fumadocs-ui/layouts/docs"; import defaultMdxComponents from "fumadocs-ui/mdx"; -import { - DocsBody, - DocsDescription, - DocsPage, - DocsTitle, -} from "fumadocs-ui/page"; +import { DocsBody, DocsPage } from "fumadocs-ui/page"; import { Mermaid } from "@/components/mermaid"; import { i18n } from "@/lib/i18n"; import { baseOptions } from "@/lib/layout.shared"; @@ -19,8 +14,9 @@ export async function loader({ params }: Route.LoaderArgs) { // 从路由参数获取语言,如果没有则使用默认语言 // URL 格式: /docs/manual/getting-started (默认语言 zh) // URL 格式: /en/docs/manual/getting-started (英语) - const lang = - params.lang && i18n.languages.includes(params.lang as any) + const lang: "zh" | "en" = + params.lang && + i18n.languages.includes(params.lang as (typeof i18n)["languages"][number]) ? (params.lang as "zh" | "en") : (i18n.defaultLanguage as "zh" | "en"); @@ -41,7 +37,7 @@ export async function loader({ params }: Route.LoaderArgs) { } const clientLoader = browserCollections.docs.createClientLoader({ - component({ toc, frontmatter, default: Mdx }) { + component({ toc, default: Mdx }) { return ( {/* 老王说不要这个 */} @@ -67,7 +63,7 @@ const clientLoader = browserCollections.docs.createClientLoader({ }, }); -export default function Page({ loaderData, params }: Route.ComponentProps) { +export default function Page({ loaderData }: Route.ComponentProps) { const { pageTree, lang } = useFumadocsLoader(loaderData); return ( diff --git a/packages/docs/app/routes/home.tsx b/packages/docs/app/routes/home.tsx index fe561e4..26c0f52 100644 --- a/packages/docs/app/routes/home.tsx +++ b/packages/docs/app/routes/home.tsx @@ -110,7 +110,7 @@ const texts = { }, }; -export function meta({ params }: Route.MetaArgs) { +export function meta() { return [ { title: "DropOut - Modern Minecraft Launcher" }, { @@ -172,9 +172,9 @@ export default function Home({ params }: Route.ComponentProps) { {/* Features Grid */}
- {t.features.items.map((item, i) => ( + {t.features.items.map((item) => (

{item.title}

@@ -187,8 +187,8 @@ export default function Home({ params }: Route.ComponentProps) {

{t.why.title}

- {t.why.items.map((item, i) => ( -
+ {t.why.items.map((item) => ( +

{item.q}
-- cgit v1.2.3-70-g09d2 From 8f2f72a857083122bce14277089ebccd64312061 Mon Sep 17 00:00:00 2001 From: NtskwK Date: Thu, 26 Mar 2026 10:00:35 +0800 Subject: fix(mermaid): update chart dependency in effect --- packages/docs/app/components/mermaid.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'packages/docs/app') diff --git a/packages/docs/app/components/mermaid.tsx b/packages/docs/app/components/mermaid.tsx index 85ab342..d408aad 100644 --- a/packages/docs/app/components/mermaid.tsx +++ b/packages/docs/app/components/mermaid.tsx @@ -13,11 +13,12 @@ export function Mermaid({ chart }: { chart: string }) { useEffect(() => { if (ref.current) { + ref.current.innerHTML = chart; mermaid.run({ nodes: [ref.current], }); } - }, []); + }, [chart]); return (

-- cgit v1.2.3-70-g09d2 From 14832b994f2ad504c70f5e101ddfa96018e657d6 Mon Sep 17 00:00:00 2001 From: NtskwK Date: Thu, 26 Mar 2026 10:08:23 +0800 Subject: chore(docs): refactor Mermaid component to render charts asynchronously and improve security --- packages/docs/app/components/mermaid.tsx | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'packages/docs/app') diff --git a/packages/docs/app/components/mermaid.tsx b/packages/docs/app/components/mermaid.tsx index d408aad..04d89d9 100644 --- a/packages/docs/app/components/mermaid.tsx +++ b/packages/docs/app/components/mermaid.tsx @@ -6,25 +6,36 @@ import { useEffect, useRef } from "react"; mermaid.initialize({ startOnLoad: false, theme: "default", + securityLevel: "strict", }); export function Mermaid({ chart }: { chart: string }) { const ref = useRef(null); useEffect(() => { - if (ref.current) { - ref.current.innerHTML = chart; - mermaid.run({ - nodes: [ref.current], - }); - } + const renderChart = async () => { + if (!ref.current) return; + + try { + const id = `mermaid-${Math.random().toString(36).slice(2, 9)}`; + const { svg } = await mermaid.render(id, chart); + // Use innerHTML with sanitized SVG from mermaid.render + // biome-disable-next-line security/noInnerHtml + ref.current.innerHTML = svg; + } catch { + // Invalid chart definition, render nothing + if (ref.current) { + ref.current.innerHTML = ""; + } + } + }; + + renderChart(); }, [chart]); return (
-
- {chart} -
+
); } -- cgit v1.2.3-70-g09d2 From 62d8c7c5c3bc36fbaa1bfba099e3bf04a00c300d Mon Sep 17 00:00:00 2001 From: NtskwK Date: Thu, 26 Mar 2026 10:18:46 +0800 Subject: refactor(mermaid): improve svg rendering with DOMParser --- packages/docs/app/components/mermaid.tsx | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'packages/docs/app') diff --git a/packages/docs/app/components/mermaid.tsx b/packages/docs/app/components/mermaid.tsx index 04d89d9..3a54a04 100644 --- a/packages/docs/app/components/mermaid.tsx +++ b/packages/docs/app/components/mermaid.tsx @@ -13,24 +13,20 @@ export function Mermaid({ chart }: { chart: string }) { const ref = useRef(null); useEffect(() => { - const renderChart = async () => { - if (!ref.current) return; - - try { - const id = `mermaid-${Math.random().toString(36).slice(2, 9)}`; - const { svg } = await mermaid.render(id, chart); - // Use innerHTML with sanitized SVG from mermaid.render - // biome-disable-next-line security/noInnerHtml - ref.current.innerHTML = svg; - } catch { - // Invalid chart definition, render nothing - if (ref.current) { - ref.current.innerHTML = ""; + const id = `mermaid-${Math.random().toString(36).slice(2, 9)}`; + mermaid + .render(id, chart) + .then(({ svg }) => { + const parser = new DOMParser(); + const doc = parser.parseFromString(svg, "image/svg+xml"); + const svgEl = doc.querySelector("svg"); + if (ref.current && svgEl) { + ref.current.replaceChildren(svgEl); } - } - }; - - renderChart(); + }) + .catch(() => { + ref.current?.replaceChildren(); + }); }, [chart]); return ( -- cgit v1.2.3-70-g09d2 From d69e408ece77d011d7097a711636f7edf9b0756c Mon Sep 17 00:00:00 2001 From: NtskwK Date: Thu, 26 Mar 2026 10:22:16 +0800 Subject: fix(mermaid): prevent memory leak on unmount --- packages/docs/app/components/mermaid.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'packages/docs/app') diff --git a/packages/docs/app/components/mermaid.tsx b/packages/docs/app/components/mermaid.tsx index 3a54a04..fe153ec 100644 --- a/packages/docs/app/components/mermaid.tsx +++ b/packages/docs/app/components/mermaid.tsx @@ -13,10 +13,12 @@ export function Mermaid({ chart }: { chart: string }) { const ref = useRef(null); useEffect(() => { + let current = true; const id = `mermaid-${Math.random().toString(36).slice(2, 9)}`; mermaid .render(id, chart) .then(({ svg }) => { + if (!current) return; const parser = new DOMParser(); const doc = parser.parseFromString(svg, "image/svg+xml"); const svgEl = doc.querySelector("svg"); @@ -25,8 +27,11 @@ export function Mermaid({ chart }: { chart: string }) { } }) .catch(() => { - ref.current?.replaceChildren(); + if (current) ref.current?.replaceChildren(); }); + return () => { + current = false; + }; }, [chart]); return ( -- cgit v1.2.3-70-g09d2