-
-
Notifications
You must be signed in to change notification settings - Fork 6.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Server Side Support #3650
Comments
This would also greatly help the Alternative Solutionssvgdom might help as well, as it adds a bunch of SVG DOM features to Node.JS. IssuesWe'd most likely have to change the default font to an open-source font too, since the default fonts are owned by Microsoft:
I'd recommend https://fonts.google.com/specimen/Atkinson+Hyperlegible as a good default, since it's designed for people with low vision, and it's available under the Open Font License. The license is very permissive, we just need to:
|
This could also enable the generation of diagram previews when linking to live editor. |
Lots of possibilities with this one. |
We just finished the integration of Mermaid in Docusauurs (facebook/docusaurus#7490) We would also really like to have SSR support:
Important thing to consider: it would be great if the SVG output did use CSS variables so that we can do theming and support dark/light mode:
|
Exciting stuff! I'm looking forwards to the next Docusaurus release then! 🚀 I do have a server-side rendering (SSR) plugin for remark called remark-mermaid-dataurl that works for docusaurus, but the way it works is by using
It might be easier to hard-code them for a few reasons:
Docusaurus would always be able to override the Mermaid default CSS with their own custom CSS using the Although, adding server-side rendering support to Mermaid will probably take a while, so maybe some of these considerations will change over time. |
Would you be open to integrate a mechanism to convert text to SVG paths (such as https://maker.js.org/ or https://github.com/vercel/satori)? It would solve font cut-off issues when a diagram is generated server-side because the font is very likely not going to be rendered identically on the client side. |
This is something I've been interested in for a while, I currently use mermaid with gatsby for my blog. (including maintaining a fork of a plugin to prerender diagrams with puppeteer. I may start experimenting with this over the holiday break--puppeteer is easily the most fragile part of my static site build. I saw others successfully leverage jsdom to render d3 charts, so I think I'll probably start there @aloisklink do you know of any obvious stumbling blocks for that approach? @Mogztter that's an interesting idea, did you have any thoughts on how to address the SEO and accessibility concerns of such an approach? Charts tend to be much more vital to understanding the content of a page than other types of figures, and removing all text might cause problems with this. |
I think we should use the
|
Also just to make sure I understand the issue you're describing:
does that sum it up correctly? |
That's correct!
Actually, Mermaid calculates the spacing/size of boxes based on the rendered size of the text (contained in it) using a given font and rendering engine (browser). When you open the generated SVG generated on another machine/browser the font will be rendered differently, small differences on the letter spacing but in then end the text can exceed the box width. |
It would be better to bundle the fonts somehow (e.g. if using The only issue is then we'd be limited to fonts with an open-source license (but that's probably a good thing! The default Mermaid font of Tahoma is owned by Microsoft, so can be hard to install on Linux. Maybe https://fonts.google.com/specimen/Atkinson+Hyperlegible is a good option).
We already have a
As far as I'm aware, that's correct. And since PRs are always welcome if anybody wants to try it out, though!
If both the server and client have the exact same font and same CSS settings, it might be that the generated SVGs are similar enough that letter spacing won't change. From my limited experience with mermaid-cli and remark-mermaid-dataurl (which use puppeteer), pre-generated SVGs look mostly identical to client-generated SVGs, as long as both computers had the same fonts installed. But I am mainly testing Ubuntu x86_64 machines using Chromium, so there's not a lot of variety there. |
I was thinking of different ways to do this, and I wanted to talk about solution combos. One mentioned here was:
I would like to compile mermaid to a wasm so it can be portable and more secure/sandboxed, and used more easily in different places. One of the key items that Mermaid is missing is the layout engine, but the expense of the browser is quite a lot. rust + servo + mermaid -> wasm This looks like a problem that would really be nice to have a lighter solution for, but also pretty involved. So it would be nice to fined a path that looks like it will have a good performance/size result in the end and be flexible for embedding. If anyone has more or better ideas I would like to hear them. |
@taylorh140, my recommendation would be to solve the deeper problem. The reason why MermaidJS cannot be easily run server-side (outside of a browser environment) is because it doesn't generate SVG-compliant output. While leveraging browser features (i.e., HTML/CSS) may make development faster/simpler to generate complex SVG diagrams, it comes with the disadvantage that nearly every third-party SVG library available cannot handle embedded HTML. (After all, why should an SVG library be burdened with also implementing a non-trivial chunk of the HTML/CSS specification?) @jgreywolf is looking into this problem. See issue #2485 for details. |
FYI, I think these are two separate issues. Converting MermaidJS to create SVG 1.1 compliant SVGs would be easier, we just need to avoid using HTML in diagrams (I believe many diagrams already have a I believe
This might be a struggle, see servo/servo#28070 yoga is a C++ layout engine that has a WASM version on npm, see https://www.npmjs.com/package/yoga-layout, but unfortunately it doesn't yet support text layout. (although we might be able to hack it it together, with a fixed font like https://github.com/DioxusLabs/taffy/blob/daf416438b5379bf4d8b3dd79ab20c8bc78754aa/tests/generated/mod.rs#L8-L62, since Yoga does support adding your own text |
From @aloisklink 's comments:
My understanding is that
See also:
When #1431 is finished, maybe it'll work? I don't know how many graphs support that option. |
FYI, in two days I will be locked out of my account once GitHub begins enforcing MFA. Sorry I won't be able to help any further. |
By the way, I decided to use Pintora instead which has fewer features, but which renders entirely on the server side. It works fine in an Astro component: ---
import {createHash} from 'node:crypto'
import {PintoraConfig} from '@pintora/standalone';
import {render} from '@pintora/cli'
interface Cache {
[key: string]: string;
}
export interface Props {
config?: PintoraConfig;
code: string;
}
const cache: Cache = {}
const generateHash = (input: string) => {
const hash = createHash('sha256')
hash.update(input)
return hash.digest().toString('hex')
}
const {config, code} = Astro.props
const uniqueKey = generateHash(JSON.stringify(Astro.props));
if (cache[uniqueKey] === undefined) {
/* Render the mermaid diagram */
try {
const result = await render({
code: code,
pintoraConfig: config,
mimeType: 'image/svg+xml'
});
if (typeof result === 'string' && result !== '') {
cache[uniqueKey] = result;
} else if (result instanceof Buffer) throw new Error('Unexpected buffer')
} catch (error) {
console.error(error)
}
}
---
{
cache[uniqueKey] && (
<div class="pintora">
<Fragment set:html={cache[uniqueKey]}/>
</div>
)
}
<style>
.pintora {
/* Necessary to avoid pixelated font rendering on macOS/Chrome, why? */
/* Also, why this looks awful on Safari with every settings tested? */
-webkit-font-smoothing: auto;
-moz-osx-font-smoothing: auto;
/* Necessary for Safari, which doesn't make the SVG full width, why? */
display: flex;
justify-content: center;
width: 100%;
}
</style> |
This really needs fixed |
Thank you for sharing Pintora; we're going to try it out! 🎉 We use Mermaid right now at Forward Email (@forwardemail) and we have had an absolute headache with it due to this issue. Definitely looking to switch. |
Glad I could help! If you use Astro, I published a component: https://github.com/tex0l/astro-pintora |
👋 Hi there folks! 💬 What's this comment about? Here at Forward Email (@forwardemail) - we tried out Mermaid (v6-latest), then we tried Pintora Standalone, then we tried Pintora CLI, then we tried Mermaid again, and then finally Mermaid CLI. Unfortunately both Mermaid and Pintora have Content-Security-Policy ("CSP") issues if used client-side - and they also have issues with server-side rendering (or rendering in general). Ultimately we ended up using Mermaid CLI to render the assets with retina and dark/light mode theme support. Albeit it's not pretty, it has built-in caching and works remarkably well. We wanted to share it here with the community 🎉... 🔴 Live Demo: https://forwardemail.net/blog/docs/best-quantum-safe-encrypted-email-service#how-does-it-work 🚧 How does it work?
❓ Why bother? We were aiming to pass 100% on all tests (and we did; as far as we know we're the only email service to do this):
|
Hello, I am not a native English speaker, so I have used a translation tool to read the issue and write this message. I am using playwright to simulate a browser environment for server-side rendering. However, when I moved the deployment environment from GitHub Pages to Cloudflare, I encountered an issue where Cloudflare’s build tools could not install the necessary browser environment. As a result, I have to continue using GitHub Actions for the build process. Although the problem can be resolved by building in GitHub Actions and then deploying to Cloudflare, I am looking for a better solution. From what I have read in the issue discussion, it seems there is no direct solution yet, and the workaround involves adding additional dependencies. I am curious to know if this problem is on the roadmap or if the MermaidJS team is aware of and actively monitoring this issue? |
Hi, I'm technically a member of the @mermaid-js team (although I focus more on the https://github.com/mermaid-js/mermaid-cli project), and this is a big wishlist item for me! But it most likely won't happen anytime soon. We'd need some sort of tool with a layout engine. One of the jsdom engineers estimated it would take a very talented engineer 3-6 months working full-time to add it to jsdom: jsdom/jsdom#1322 (comment). I'm still hoping that https://servo.org/ might do the job, once it's done! If you look at https://wpt.servo.org/, they're slowly implementing more and more CSS features! |
Several thoughts on the subject:
|
Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
Support for server-side rendering of Mermaid.js such as Node.js
Describe the solution you'd like
A clear and concise description of what you want to happen.
This has been discussed in #559 and #1183. I looked into the source code and noticed that a browser environment is required to precompute widths/heights. Just saw this project, maybe we can use Vercel's Satori. It internally uses Facebook's Yoga, a cross-compatible flexbox implementation.
The text was updated successfully, but these errors were encountered: