1

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"

Rowin_nb2
  • 164
  • 1
  • 13

0 Answers0