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)
}