felleslosninger/tlp-react

Explore options to make components support SSR

Opened this issue · 3 comments

Description of the bug

I have been testing the components with Next.js` new App router, and have discovered some issues:

  • If client side hooks are being used in SSR, React will complain with: React.createContext error.
  • The computed styles from the CSS modules do not work even if the component itself supports SSR. No styles are loaded when the page first loads.
  • On a client side component there is an issue where the computed styles from the CSS modules are delayed. The computed styles are not applied on the initial server payload, but on the second pass. This means that there will be a split second where no styles are being applied.

Steps To Reproduce

I created a repo with instructions on how to replicate the issues with a server and a client component:
https://github.com/Thuneer/next-ssr

Suggested resolutions

  • Mantine recently added SSR support for their components: https://mantine.dev/changelog/7-0-0/. They are also using CSS modules that won't work with SSR, but they are building a CSS file by scanning all the CSS modules. This file can then be sent with the server payload on Next-js.
  • Go through all the tlp-react components and make sure they support SSR. Maybe we should create a Next.js app Router project in this repo that we can use to test. We have to use SSR friendly hooks.

Comment with notes, no need to read:
It seems like client components compute their style in the browser, and then adds them to in a <style> tag.
If I make my own component directly in the repo, with css modules, it moves the css into a file, and it will be sent with the payload, and not computed by the browser.

The reason why we don't see styles on a server component, is simply because there is "no place" for the generated styles to go.

We either need to make a full css file that will always be present, or bundle the styles into the component, possibly inline.

What is fun here is that if you build the repo, then serve it, everything works fine, but you still see a quick flash of no style.

Making static CSS files for components are pretty easy - We just need to generate them with a name, and then make sure the exported components through rollup has the same generated name as in the CSS. FileCard and LinkList don't support SSR yet, as they rely on @digdir/design-system-react components.

As you an see in the image below, the CSS for the components comes from a file, and not a <style> tag:
image

We use generate-css.ts to create the CSS files, and also concat all created files into a global.css file.

We use hash-css-names.mjs to generate hashed names for the classes. We prfix them with tlp, but this can be changed to anything.

The client side styling that used to happen (the flash of no style, and then style) is gone, and every style has to come from a .css file that needs to be imported.
This is because in our postcss() rollup plugin, we wass extract: true.
Can be seen here