I'm using NextJS with Static Site Generation, Marked and PrismJS to render markdown with styling for codeblocks.
Unfortunately I'm keep getting the warning: Warning: Prop 'dangerouslySetInnerHTML' did not match. Server: ... Client: ...
[slug].tsx
import fs from "fs";
import Head from "next/head";
import { parseMarkdown } from "../../components/parseMarkdown";
import { ArticleMeta } from "../../components/ArticleMeta";
import { markdownParser } from "../../components/utils/RichContent/Markdown";
import { ImageComponent } from "../../components/ImageComponent";
import { findDirectoryOfPost, getBlogArticleNames } from "../../components/getBlogArticles";
import { ShareOnSocials } from "../../components/ShareOnSocials";
import prism from "prismjs";
import { useEffect } from "react";
import { marked } from "marked";
import 'prismjs/components/prism-css';
import 'prismjs/components/prism-javascript';
import 'prismjs/components/prism-typescript';
import 'prismjs/components/prism-jsx';
import 'prismjs/components/prism-tsx';
import "prismjs/themes/prism-tomorrow.css";
const ArticlePage = ({ metadata, content }: any) => {
const title = `${metadata.title} • Charow`;
useEffect(() => {
if (typeof window !== "undefined") {
prism.highlightAll();
}
}, []);
return (
<div className="article-page">
<main>
<section className="article-page__content container">
<div className="article container--700">
<div className="rich-article" dangerouslySetInnerHTML={{ __html: content }} />
</div>
</section>
</main>
</div>
);
};
export const getStaticPaths = async () => {
const files = getBlogArticleNames();
return {
paths: files.map((filename) => ({
params: {
articleSlug: filename.replace(".md", ""),
},
})),
fallback: false,
};
};
export const getStaticProps = async ({ params: { articleSlug } }: any) => {
const directory = findDirectoryOfPost(articleSlug);
const fileContent = fs.readFileSync(`posts/${directory}/` + articleSlug + ".md").toString();
const currentArticle = parseMarkdown(fileContent);
marked.setOptions({
highlight: (code, lang) => {
if (prism.languages[lang]) {
return prism.highlight(code, prism.languages[lang], lang);
} else {
return code;
}
},
});
const parsedMarkdown = marked(currentArticle.content);
return {
props: {
metadata: currentArticle.metadata,
content: parsedMarkdown,
},
};
};
export default ArticlePage;
I can imagine that the client code looks different from the server and that's why the warning is popping up. The problem here is I don't know a way to keep the code the same on the client AND server while using PrismJS to highlight code syntax in the markdown.
(fyi: the code works even with the with warning)
Edit1:
'prism.highlightAll();' needs the document, that's why I wrote it in the if statement to see if window !== "undefined"