diff --git a/src/components/markdown-content.tsx b/src/components/markdown-content.tsx index c5af425..773098b 100644 --- a/src/components/markdown-content.tsx +++ b/src/components/markdown-content.tsx @@ -9,6 +9,20 @@ type MarkdownContentProps = Readonly<{ html: SanitizedHtml }> +const DEFAULT_KATEX_CSS_PATH = "/katex/katex.min.css" + +/** + * GitHub Pages 서브경로(e.g. /repo/) 배포 환경을 지원하기 위해 + * 환경변수 NEXT_PUBLIC_BASE_PATH 가 지정된 경우 KaTeX 스타일시트 경로 앞에 접두사로 조합합니다. + */ +export function getKatexStylesheetUrl(): string { + // biome-ignore lint/complexity/useLiteralKeys: tsconfig noPropertyAccessFromIndexSignature requires bracket access + const basePath = process.env["NEXT_PUBLIC_BASE_PATH"]?.trim() ?? "" + const normalizedBasePath = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath + + return `${normalizedBasePath}${DEFAULT_KATEX_CSS_PATH}` +} + const markdownContentClassName = cn( "prose prose-neutral max-w-none text-foreground dark:prose-invert", "prose-a:text-foreground prose-a:decoration-border prose-a:underline-offset-4", @@ -30,7 +44,9 @@ export function MarkdownContent({ contentKey, hasDiagram, hasMath, html }: Markd return ( <> - {hasMath ? : null} + {hasMath ? ( + + ) : null}
{ + const originalEnv = process.env + + beforeEach(() => { + process.env = { ...originalEnv } + }) + + afterEach(() => { + process.env = originalEnv + }) + it("Given repository-owned KaTeX assets When checking the public directory Then includes CSS and its license", () => { expect(existsSync(stylesheetPath)).toBe(true) expect(existsSync(licensePath)).toBe(true) @@ -34,4 +45,18 @@ describe("local KaTeX assets", () => { expect(packageJson).not.toMatch(/^\s*"katex":/m) expect(packageJson).not.toContain("copy-katex-assets") }) + + describe("getKatexStylesheetUrl", () => { + it("Given no NEXT_PUBLIC_BASE_PATH When resolving Then returns root stylesheet path", () => { + // biome-ignore lint/complexity/useLiteralKeys: tsconfig noPropertyAccessFromIndexSignature requires bracket access + delete process.env["NEXT_PUBLIC_BASE_PATH"] + expect(getKatexStylesheetUrl()).toBe("/katex/katex.min.css") + }) + + it("Given NEXT_PUBLIC_BASE_PATH When resolving Then prepends base path with normalized slashes", () => { + // biome-ignore lint/complexity/useLiteralKeys: tsconfig noPropertyAccessFromIndexSignature requires bracket access + process.env["NEXT_PUBLIC_BASE_PATH"] = "/my-blog/" + expect(getKatexStylesheetUrl()).toBe("/my-blog/katex/katex.min.css") + }) + }) })