Bs-css, Next JS and SSR


#1

Hello everyone,

Has anyone managed to make bs-css work with NextJS doing SSR with styles work? I mean, inserting styles into initial static html sent to client ?


#2

Iā€™ve gotten this working with Emotion V9 in the past by following the NextJS Example.

Since bs-css uses Emotion V10 under the hood, and NextJS should just work with Emotion V10 out of the box, Iā€™m a tad surprised this doesnā€™t work.

What versions of packages are you using and do you have a minimal reproducible example?


#3

I guess you did something like creating a ā€œ_document.jsā€ into ā€œpagesā€ folder and put some code like that:

import { extractCritical } from 'emotion-server';

export default class MyDocument extends Document {
  static getInitialProps({ renderPage }) {
    const page = renderPage();
    const styles = extractCritical(page.html);
    return { ...page, ...styles };
  }
  ...
}

For previous versions of emotion 10, this setup was required to manage emotion work with next, but from version 10 this is not required anymore, I think it might be because of this.

Iā€™m not using it on any current project actually I was just trying to figure out how it could be done. Iā€™m playing with the latest versions. No I donā€™t have an example but itā€™s very simple create a project:

npx create-next-app --example with-reasonml my-reason-project
npm install bs-css (donā€™t forget to put bs-css in your bsconfig dependencies section)

Then you can try style some component, and disable the javascript on your browser. From that you notice two things:

  • The classnames are generated on server.
  • The styles are put into section on client only when browser loads the page.

I donā€™t see much value on SSR if the result of that doesnā€™t have styles, the page just looks very broken. We could actually use normal CSS static files for working around that, but Css-In-JS has been proved very beneficial.

If no one else has already a standard solution for that, Iā€™ll try do to that by myself and PR to bs-css, dont think it should be that hard.


#4

Did it :smiley:

Here is an example how it could be done:

files to look:

1 - ./emotion-server.js
2 - ./pages/_document.js


#5

Thanks @nickmarca, that was really helpful!

If anyone is looking for a solution on gatsby projects, I got mine working correctly with bs-css on SSR by adding this snippet to my gatsby-ssr.js

import { renderToString } from "react-dom/server"
import { renderStylesToString } from 'emotion-server'

export const replaceRenderer = ({ bodyComponent, replaceBodyHTMLString }) => {
  const bodyHTML = renderToString(bodyComponent)
  const resultHTML = renderStylesToString(bodyHTML)
  replaceBodyHTMLString(resultHTML)
}