fix(markdown): re-render code blocks after Shikiji loads
Some checks failed
CI / verify (push) Failing after 7s

The singleton `md` instance is mutated by `useShikiji()` asynchronously,
but `content` computeds had no reactive dep on that loading, so the
initial render on page reload never picked up syntax highlighting.
Link-click navigation appeared to work only because Shikiji was already
installed in `md` by an earlier render.
This commit is contained in:
Julien Calixte
2026-06-09 14:38:40 +02:00
parent cdfc90f7eb
commit ac3a641b22

View File

@@ -13,7 +13,7 @@ import markdownItIframe from "markdown-it-iframe"
import Shikiji from "markdown-it-shikiji" import Shikiji from "markdown-it-shikiji"
import mermaid from "mermaid" import mermaid from "mermaid"
import type { LanguageRegistration } from "shikiji-core" import type { LanguageRegistration } from "shikiji-core"
import { Ref, toValue } from "vue" import { Ref, ref, toValue } from "vue"
import { data } from "@/data/data" import { data } from "@/data/data"
import { DataType } from "@/data/DataType.enum" import { DataType } from "@/data/DataType.enum"
@@ -142,6 +142,7 @@ const md = new MarkdownIt({
}) })
let shikijiPromise: Promise<void> | null = null let shikijiPromise: Promise<void> | null = null
const shikijiReady = ref(false)
export const useShikiji = (): Promise<void> => { export const useShikiji = (): Promise<void> => {
if (!shikijiPromise) { if (!shikijiPromise) {
@@ -168,6 +169,7 @@ export const useShikiji = (): Promise<void> => {
] ]
}).then((plugin) => { }).then((plugin) => {
md.use(plugin) md.use(plugin)
shikijiReady.value = true
}) })
} }
return shikijiPromise return shikijiPromise
@@ -391,6 +393,11 @@ const stripFrontmatter = (content: string): string => {
} }
const renderMarkdown = (content: string, env?: Record<string, unknown>) => { const renderMarkdown = (content: string, env?: Record<string, unknown>) => {
// Track Shikiji readiness so reactive consumers (e.g. the `content`
// computed in useFile) re-render once `useShikiji()` mutates the
// singleton `md` — otherwise the first render on page load stays
// unhighlighted because nothing else invalidates the computed.
if (content.includes("```")) void shikijiReady.value
slugger.reset() slugger.reset()
return env ? md.render(content, env) : md.render(content) return env ? md.render(content, env) : md.render(content)
} }