import Layout from 'lib/components/layout'

export const meta = {
  title: 'Server Render',
  group: 'Getting Started',
  index: 15,
}

## 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](https://nextjs.org/docs/advanced-features/custom-document) official documentation for the effects.

Then we add the following code to the file:

```js
// NAME: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](https://github.com/unix/unix.bio/blob/template/pages/_document.tsx) is also prepared here.

### Custom Server

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

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

export default ({ children }) => <Layout meta={meta}>{children}</Layout>
