DEV Community

Kevan Stannard
Kevan Stannard

Posted on

Simple Server Side CSS with ReScript, React and Emotion

Introduction

A simple introduction to using server side CSS with ReScript, React and Emotion CSS.

ReScript version: bs-platform@8.3.3

NPM Packages

First install the packages we need.

npm i @emotion/css @emotion/server react react-dom reason-react
Enter fullscreen mode Exit fullscreen mode

This example is using the following versions:

@emotion/css@11.0.0
@emotion/server@11.0.0
react@17.0.1
react-dom@17.0.1
reason-react@0.9.1
Enter fullscreen mode Exit fullscreen mode

Update bsconfig.json

Add reason-react to bs-dependencies:

"bs-dependencies": ["reason-react"],
Enter fullscreen mode Exit fullscreen mode

Create the Emotion bindings

In a file Emotion.res add the following bindings.

module Css = {
  @bs.module("@emotion/css")
  external css: {..} => string = "css"
}

module Server = {
  @bs.module("@emotion/server")
  external renderStylesToString: string => string = "renderStylesToString"
}
Enter fullscreen mode Exit fullscreen mode

Render a component with some styles

In a test file, create some styles to use:

module Styles = {
  open Emotion.Css
  let container = css({"border": "1px solid black"})
}
Enter fullscreen mode Exit fullscreen mode

Create a React component that uses the styles:

module Container = {
  @react.component
  let make = (~children) => {
    <div className={Styles.container}> {children} </div>
  }
}
Enter fullscreen mode Exit fullscreen mode

Render the component with Emotion styles:

let el = <Container> {ReasonReact.string("Hello")} </Container>


let html =
  el
  ->ReactDOMServer.renderToStaticMarkup
  ->Emotion.Server.renderStylesToString
Enter fullscreen mode Exit fullscreen mode

Which generates the following code (reformatted here for readability):

<style data-emotion="css 1r0rfp">
  .css-1r0rfp{border:1px solid blue;}
</style>
<div class="css-1r0rfp">Hello</div>
Enter fullscreen mode Exit fullscreen mode

Note

If you would prefer stronger type safety with Emotion, you may like to use bs-css.

Top comments (0)