Closed Stratis-Dermanoutsos closed 2 years ago
Thanks for reporting @Stratis-Dermanoutsos! Yes, it looks like mermaid
is included in Shiki's default language list. I'll investigate why we're missing this 👍
@Stratis-Dermanoutsos, #4519 should address your issue. If you are looking for a implementation of Mermaid in Astro like GitHub does, you can check out my webpage, where I've done that: mermaid.ts, Layout.astro
@JuanM04 Thank you man! Your comment was extremely helpful in implementing Mermaid in my personal Astro site :) Note for anyone trying to replicate - this implementation works for mermaid versions 9. but breaks for versions 10.
I downgraded mermaid version and it is working too. If anyone has a fix for mermaid 10 I'm interested !
Just for the record, I've migrated to Mermaid 10 successfully! This is the remark plugin and this is the dynamic script.
It is working for me ! Thank you very much @JuanM04 ! ❤️
@JuanM04 You're awesome, bro!
Thanks, @JuanM04, for the solution.
However, I want to optimize it by ensuring it only loads when required. More specifically, I want it to run only when the '.mermaid' elements become visible in the viewport.
The above code works, but it triggers all of my scripts for other elements that use Client Directives (client:visible
).
My question is: Is there a way to run this script during the build process instead of on the client-side?
Currently, I'm running a script with Partytown
${node.value}` }) } ``` However, this solution I don't know how to initialize mermaidAPI theme.
Not working on Astro v4 ToT. Always shows [ERROR] __vite_ssr_import_1__.default is not a function
Not working on Astro v4 ToT. Always shows
[ERROR] __vite_ssr_import_1__.default is not a function
Resolved by removing ts-dedent
. Follow at https://github.com/tamino-martinius/node-ts-dedent/issues/40.
As another approach, I use rehype-mermaid and rehype-shikiji plugins and disable astro's built-in syntax highlighting. This renders the diagrams to svg via playwright, no client-side js needed. The remaining code blocks get highlighted afterwards. You could also use e.g. rehype-pretty-code for highlighting.
import { defineConfig } from 'astro/config'
import rehypeMermaid from 'rehype-mermaid'
import rehypeShikiji from 'rehype-shikiji'
// https://astro.build/config
export default defineConfig({
markdown: {
rehypePlugins: [rehypeMermaid, [rehypeShikiji, { theme: 'github-dark' }]],
syntaxHighlight: false
},
})
In my md files, I can have mermaid syntax in code fences and they get rendered to inlined svg diagram.
The SVG render with size 24x24 only, cannot change it. Any one has solution
The SVG render with size 24x24 only, cannot change it. Any one has solution
Overriding the default style using the themeCSS
option in the Mermaid initialize API or the global CSS.
mermaid.initialize({
themeCSS: 'width: 100%; height: auto;',
// skip
});
or
.mermaid svg {
width: 100%;
height: auto;
}
Since Astro v4.5, syntax highlighting uses shiki again instead of shikiji, and internal syntax highlighting has been migrated to use rehype plugins instead of remark plugins. These plugins still run before custom plugins, so sequence matters. What has changed is that rehype-shikiji is not needed anymore and we can use the internal shiki plugin.
# Upgrade astro
npx @astrojs/upgrade
# Remove rehype-shikiji plugin
npm rm rehype-shikiji
The markdown section in astro.config.js looks like this (shortened):
import { defineConfig } from 'astro/config'
import { rehypeShiki } from '@astrojs/markdown-remark'
import rehypeMermaid from 'rehype-mermaid'
// https://astro.build/config
export default defineConfig({
markdown: {
rehypePlugins: [
rehypeMermaid,
rehypeShiki,
],
syntaxHighlight: false,
},
})
Is this still a recommended way of adding Mermaid, or am I missing some implications from the newer changes?
Just for the record, I've migrated to Mermaid 10 successfully! This is the remark plugin and this is the dynamic script.
Thanks so much for this. It worked for me after I made a few tweaks. Sharing in case it helps anyone else.
For me, using data-content
was removing line breaks, so I had to change it to dump the mermaid source into a <pre>
:
mermaid.ts
import type { RemarkPlugin } from "@astrojs/markdown-remark"
import { visit } from "unist-util-visit"
const escapeMap: Record<string, string> = {
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'",
}
const escapeHtml = (str: string) => str.replace(/[&<>"']/g, c => escapeMap[c])
export const mermaid: RemarkPlugin<[]> = () => tree => {
visit(tree, "code", node => {
if (node.lang !== "mermaid") return
// @ts-ignore
node.type = "html"
node.value = `
<div class="mermaid">
<p>Loading graph...</p>
<pre class="mermaid-src">${escapeHtml(node.value)}</pre>
</div>
`
})
}
<script>
in Layout.astro
<script>
// Source: https://github.com/JuanM04/portfolio/blob/983b0ed0eabdac37bf8b7912d3e8128a443192b9/src/pages/docs/%5B...documentSlug%5D.astro#L74-L103
// From this comment: https://github.com/withastro/astro/issues/4433#issuecomment-1584019991
/**
* @params {HTMLCollectionOf<HTMLElement>} graphs
*/
async function renderDiagrams(graphs) {
const {default: mermaid} = await import("mermaid")
mermaid.initialize({
startOnLoad: false,
fontFamily: "var(--sans-font)",
// @ts-ignore This works, but TS expects a enum for some reason
theme: window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "default",
})
for (const graph of graphs) {
const content = graph.querySelector(".mermaid-src").innerText
if (!content) continue
let svg = document.createElement("svg")
const id = (svg.id = "mermaid-" + Math.round(Math.random() * 100000))
graph.appendChild(svg)
mermaid.render(id, content).then(result => {
graph.innerHTML = result.svg
})
}
}
const graphs = document.getElementsByClassName("mermaid")
if (document.getElementsByClassName("mermaid").length > 0) {
renderDiagrams(graphs);
}
</script>
astro.config.mjs
import { mermaid } from "./src/plugins/mermaid";
// ...
markdown: {
remarkPlugins: [
// ...
mermaid,
],
// ...
Used in this repo in case you're curious.
Thanks again for the solution!
@stephengrice Thank you for the detailed description in your answer, it saved me a lot of time.
After successfully rendering the mermaid diagram following the steps mentioned above, I noticed that when I use the browser's back button to return to the blog, the mermaid rendering does not work.
What version of
astro
are you using?1.0.7
Are you using an SSR adapter? If so, which one?
None
What package manager are you using?
npm
What operating system are you using?
Windows
Describe the Bug
When I am added a
mermaid
code block, it only renders as plaintext.To be more specific, when I visit the Markdown page that has any mermaid code block, the terminal logs the following:
Example code block:
(The closing ` is escaped to get printed here, in the Github preview. I don't escape it in the actual code.)
Link to Minimal Reproducible Example
https://stackblitz.com/edit/github-xn8csz
Participation