splitbee/react-notion

Props `className` did not match

thmsmlr opened this issue ยท 4 comments

Hey hey, love the project. I'm using it on my blog. I've been trying to debug something with it though. I'm using Next.js with this project. Doing some of the static page generation that came out with next.js 9.4. I've notice something weird though.

When I render a page statically and render it, everything seems fine. However, when the javascript loads on the page right after load and rehydrates the page, it will try to rerender the syntax highlight of the code blocks and throw an error that the server rendered className is not equal to the client side className. This leads the renderer to remove all of the wrapping <span> which denote the various tokens in the code block.

When you load the page with Javascript disabled, everything looks great, but the minute you enable javascript in the browser, the syntax highlight flashes and it goes to a non-highlighted state.

This is the error i'm seeing. I've dug into it a little bit, and don't have any leads on how to debug. Have you seen this? Do you have any leads on how to fix?

react-dom.development.js:530 Warning: Prop `className` did not match. Server: " language-bash" Client: "language-bash"

With JS enabled:

image

With JS disabled:

image

I was able to fix the rendering issue but not the warning!
I published a beta release on NPM.

Thanks for looking into this, I tried the latest beta 0.7.2 and i'm still having the problem. Maybe the react warning is a red herring. I'm going to spend some time debugging tonight, see what I can dig up. I'll report back

Okay, so I found the issue. Turns out the className warning was a total red herring.

The issue was that Notion was (correctly) labeling the code block as using bash as the language. This line however, defaults to javascript if it cannot find the language in that object. When I ran the chrome debugger, I found that the object didn't have bash in it at all. What I think is happening is that when next.js builds the static HTML it's using all the code available to it in the node_modules which includes all the language packages that come with prism.js. However, when it compile the final bundle for that page it minimizes the code and removes unused codepaths. This would reasonable remove any non-default language since in my case, bash was dynamically provided by an external datasource. I'm not 100% sure that's exactly happening, but it does make sense given my mental model of how next.js works.

Turns out the solution was super simple, all I did was add

import 'prismjs/components/prism-bash';

to my next.js page that uses react-notion and the problem was solved.

Thanks for looking at the issue. I think this was mostly a user error on my part. I'll submit a PR with some basic user caveats around code blocks so other users can avoid this issue

FWIW, I was thinking about this issue more in the context of next.js's domain of control and lead me to an idea of completely static components. Here's the link incase you're interested

vercel/next.js#14840