NextJS SSG with PrismJS will throw warning: Prop `dangerouslySetInnerHTML` did not match

234 Views Asked by At

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"

0

There are 0 best solutions below