Skip to content

Commit

Permalink
Tidy up the server side rendering code (segmentio#151)
Browse files Browse the repository at this point in the history
* Tidy up SSR

* console.error

* Remove production check

* Fix SSR and add next.js example app

* Fix linting
  • Loading branch information
Rowno authored Mar 7, 2018
1 parent 2472813 commit e9f96cd
Show file tree
Hide file tree
Showing 18 changed files with 5,153 additions and 199 deletions.
57 changes: 1 addition & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,62 +134,7 @@ The following file tree will be generated:

## Server Side Rendering

Evergreen bundles 2 CSS-in-JS solutions, from glamor and ui-box. To make it super
easy to do server side rendering and hydration, Evergreen exposes it's own function
that will do SSR for both at once.

### Next.js SSR example

Install a new [Next.js](https://github.com/zeit/next.js) with [create-next-app](https://github.com/segmentio/create-next-app).
Create a `_document.js` inside of the `./pages` folder with the following content:

```javascript
// ./pages/_document.js
import Document, { Head, Main, NextScript } from 'next/document'
import { extractStyles } from 'evergreen-ui'

export default class MyDocument extends Document {
static getInitialProps({ renderPage }) {
const page = renderPage()
// `css` is a string with css from both glamor and ui-box
// no need to do glamor manually if you are using it elsewhere in your app
//
// `evergreenHydrateScript` is a script you should render on the server.
// it will contain a stringified JSON of the cache of both glamor and ui-box.
// Evergreen will look for that script on the client and automatically hydrate
// both glamor and ui-box
const { css, evergreenHydrateScript } = extractStyles()
return {
...page,
css,
evergreenHydrateScript
}
}

constructor(props) {
super(props)
const { __NEXT_DATA__, ids, cache } = props
if (ids) {
__NEXT_DATA__.ids = this.props.ids
}
}

render() {
return (
<html>
<Head>
<style dangerouslySetInnerHTML={{ __html: this.props.css }} />
{this.props.evergreenHydrateScript}
</Head>
<body className="custom_class">
<Main />
<NextScript />
</body>
</html>
)
}
}
```
Evergreen bundles 2 CSS-in-JS solutions, from glamor and ui-box. To make it super easy to do server side rendering and hydration, Evergreen exposes a `extractStyles()` function that will do SSR for both at once. You can see how to use it with Next.js in the [ssr-next example app](examples/ssr-next).

## Contributors 🎉

Expand Down
3 changes: 3 additions & 0 deletions examples/ssr-next/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["next/babel"]
}
2 changes: 2 additions & 0 deletions examples/ssr-next/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/node_modules/
/.next/
18 changes: 18 additions & 0 deletions examples/ssr-next/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"private": true,
"name": "ssr-next",
"version": "1.0.0",
"license": "MIT",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
"dependencies": {
"evergreen-ui": "latest",
"next": "^5.0.0",
"react": "^16.2.0",
"react-dom": "^16.2.0"
},
"xo": false
}
39 changes: 39 additions & 0 deletions examples/ssr-next/pages/_document.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* eslint-disable react/no-danger, import/no-unresolved */
import React from 'react'
import Document, { Head, Main, NextScript } from 'next/document'
import { extractStyles } from 'evergreen-ui'

export default class MyDocument extends Document {
static async getInitialProps({ renderPage }) {
const page = renderPage()
// `css` is a string with css from both glamor and ui-box.
// No need to get the glamor css manually if you are using it elsewhere in your app.
//
// `hydrationScript` is a script you should render on the server.
// It contains a stringified version of the glamor and ui-box caches.
// Evergreen will look for that script on the client and automatically hydrate
// both glamor and ui-box.
const { css, hydrationScript } = extractStyles()
return {
...page,
css,
hydrationScript
}
}

render() {
return (
<html>
<Head>
<title>SSR in Next.js</title>
<style dangerouslySetInnerHTML={{ __html: this.props.css }} />
{this.props.hydrationScript}
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
)
}
}
5 changes: 5 additions & 0 deletions examples/ssr-next/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* eslint-disable import/no-unresolved */
import React from 'react'
import { Button } from 'evergreen-ui'

export default () => <Button>🌲</Button>
Loading

0 comments on commit e9f96cd

Please sign in to comment.