rofrischmann/fela

View on GitHub
website/docs/latest/advanced/server-rendering.mdx

Summary

Maintainability
Test Coverage
# Server Rendering

As [already mentioned](intro/benefits), Fela supports server-side rendering out of the box.
All you need to do is call [`renderToMarkup`](api/fela-dom/renderToMarkup) or, depending on your scenario, [`renderToSheetList`](api/fela-dom/renderToSheetList) once you are finished rendering styles and you will get the final HTML markup for the `<style>` elements. That's it. No magic. No extra configuration.

Usually you will render all styles on the server and inject the rendered CSS markup into the HTML markup which gets sent to the client.

## Example

The following code shows a simple server example using [express](https://github.com/expressjs/express) and [React](https://github.com/facebook/react).

```javascript name=server.js
import express from 'express'
import React from 'react'
import { createRenderer } from 'fela'
import { renderToMarkup } from 'fela-dom'
import { RendererProvider, useFela } from 'react-fela'

// simplified demo app
const App = () => {
  const { css } = useFela()

  return (
    <div className={css({ color: 'blue', fontSize: '15px' })}>Hello World</div>
  )
}

// Our initial html template
const appHTML = `
<!DOCTYPE html>
<html>
<head>
  <title>Fela - Server Rendering</title>
  {{style}}
</head>
<body>
  <div id="app">
    {{app}}
  </div>
</body>
</html>
`

const server = express()

server.get('/', (req, res) => {
  const renderer = createRenderer()

  renderer.renderStatic(
    {
      margin: 0,
      padding: 0,
    },
    'html, body'
  )

  const htmlMarkup = renderToString(
    <RendererProvider renderer={renderer}>
      <App />
    </RendererProvider>
  )

  const styleMarkup = renderToMarkup(renderer)
  // inject the rendered html and css markup into the basic app html
  res.write(
    appHTML.replace('{{app}}', htmlMarkup).replace('{{style}}', styleMarkup)
  )
  res.end()
})
// provide the content via localhost:8080
server.listen(8080, 'localhost')
```

### Rendered Markup

```html name=index.html
<!DOCTYPE html>
<html>
  <head>
    <title>Fela - Server Rendering</title>
    <style type="text/css" data-fela-type="STATIC">
      html,
      body {
        margin: 0;
        padding: 0;
      }
    </style>
    <style type="text/css" data-fela-type="RULE">
      .a {
        color: blue;
      }
      .b {
        font-size: 15px;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <div class="a b">Hello World</div>
    </div>
  </body>
</html>
```

## Advanced Usage

The above example highlights the basic mechanics, but we do not recommend writing your own SSR logic. <br />
There are tools such as [Next](https://nextjs.org) and [Gatsby](https://www.gatsbyjs.com) which can do that for you in a way more clever way. <br/>

> Check out all existing [Integrations](intro/ecosystem#integrations).

---

## Related

- [API Reference - `renderToMarkup`](api/fela-dom/renderToMarkup)
- [API Reference - `renderToSheetList`](api/fela-dom/renderToSheetList)
- [API Reference - `rehydrate`](api/fela-dom/rehydrate)