Server Render

All Components of Geist UI are compatible with Server Render. In fact, the document you see now is rendered by the server.

A common React component rendered as an HTML string on the server side usually has two parts: HTML skeleton and styles, together, they form the first string returned to the request, which effectively ensures that the user reads the page content as early as possible. (without having to wait for additional JavaScript resources to be loaded and parsed)

In Geist, all you have to do is add the style string generated by Geist to the server-side rendering tool, whether it's Next.js or a self-built HTTP server.

Next.js

In next.js framework, you need customization file _document.js, Please refer to Next.js official documentation for the effects.

Then we add the following code to the file:

pages/_document.js
import { Fragment } from "react"
import Document, { Html, Head, Main, NextScript } from 'next/document'
import { CssBaseline } from '@geist-ui/core'

class MyDocument extends Document {
  static async getInitialProps (ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    const styles = CssBaseline.flush()

    return {
      ...initialProps,
      styles: [
        <Fragment key="1">
          {initialProps.styles}
          {styles}
        </Fragment>,
      ],
    }
  }

  render() { ... }
}

The flush method in the example is used to collect the styles generated by Geist in the current page, only needs to be set once per project. A complete application example is also prepared here.

Custom Server

In the custom server, also get the style set from function CssBaseline.flush as shown below.

import React from 'react'
import ReactDOM from 'react-dom/server'
import { CssBaseline } from 'geist-ui/core'
import App from './app'

export default (req, res) => {
  const app = ReactDOM.renderToString(<App />)
  const styles = CssBaseline.flush()
  const html = ReactDOM.renderToStaticMarkup(
    <html>
      <head>{styles}</head>
      <body>
        <div id="root" dangerouslySetInnerHTML={{ __html: app }} />
      </body>
    </html>,
  )
  res.end('<!doctype html>' + html)
}