Next.js + Styled Components The Really Simple Guide ▲ + 💅
Tags: react, nextjs, ssr, javascript
Published: 2018-06-27 11:57:04

---
title: Next.js + Styled Components The Really Simple Guide ▲ + 💅
published: true
description: This guide features how you use a different styling solution than styled-jsx that also supports universal styles. That means we can serve the required styles for the first render within the HTML and then load the rest in the client.
tags: react, next.js, ssr, javascript
cover_image: https://thepracticaldev.s3.amazonaws.com/i/bc0h3lav5bvg04pn5mxv.png
---

I recently started using [Next.js](https://nextjs.org/), and quite honestly I have to say, is an awesome tool, you get a lot out of the box, and while there are some things I don't necessary agree with, overall it makes really simple to create static and server‑rendered applications.

Next comes bundled with [styled-jsx](https://github.com/zeit/styled-jsx), which is a full, scoped and component-friendly CSS support for JSX (rendered on the server or the client), and while this is great, I rather use styled components, it's just my preference.

This guide features how you use a different styling solution than [styled-jsx](https://github.com/zeit/styled-jsx) that also supports universal styles. That means we can serve the required styles for the first render within the HTML and then load the rest in the client.

Next.js has an [example repo](https://github.com/zeit/next.js/tree/canary/examples/with-styled-components) that already comes with styled components, but you need to clone it and then try to understand what is happening under the hood, I decided to make this quick and really simple guide that illustrates the process of making styled components work with next.js.

Lets get to it!

## 1. Create a project directory and install next and react dependencies

```
mkdir my-next-app && cd my-next-app && yarn add next react react-dom

```
> Next.js only supports [React 16](https://reactjs.org/blog/2017/09/26/react-v16.0.html).
>We had to drop React 15 support due to the way React 16 works and how we use it.
>
>- [Next.org](https://nextjs.org/)

## 2. Add scripts to your `package.json`

```js
{
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "next": "^...",
    "react": "^...",
    "react-dom": "^..."
  }
}
```
*After that, the file-system is the main API. Every `.js` file becomes a route that gets automatically processed and rendered.*

## 3. Create a /pages directory and your first page.

From your project root directory:

```
mkdir pages && touch pages/index.js
```
Populate `./pages/index.js`:

```jsx
export default () => (
   <div>
       <h1>My First Next.js Page</h1>
   </div>
)
```
and then just run `yarn dev` and go to `http://localhost:3000`.

![localhost:3000](https://www.adrianprieto.com/wp-content/uploads/2018/06/run.png)

So far, we get:

* Automatic transpilation and bundling (with webpack and babel)
* Hot code reloading
* Server rendering and indexing of `./pages`

## 4. Add styled-components 

```
yarn add styled-components
```
Let's now edit `./pages/index.js`:


```jsx
import styled from 'styled-components';

export default () => (
  <div>
    <Title>My First Next.js Page</Title>
  </div>
);

const Title = styled.h1`
  color: red;
`;
```

If you reload the page, you will get an error, this is because we haven’t set up the correct configuration yet, not to worry, we are doing that next.

## 5. Add babel plugin and custom `.bablerc` file

First, lets install the styled components babel plugin as a dev dependency:

```
yarn add -D babel-plugin-styled-components
```

Then create a `.babelrc` file in the root of the project.

```
touch .babelrc
```

* Add a babel/preset
* Add a styled-components plugin, set the `ssr` flag to `true`, `displayName` to `true` and `preprocess` to false.

The final `.babelrc` file should look like this:

```js
{
  "presets": [
    "next/babel"
  ],
  "plugins": [
    [
      "styled-components",
      {
        "ssr": true,
        "displayName": true,
        "preprocess": false
      }
    ]
  ]
}
```

**Note:** `displayName` will generate class names that are easier to debug (will contain also the component name instead of just hashes); `preprocess` – experimental feature turned off explicitly.

## 6. Create the custom `_document.js` file

If you have used `create-react-app` before, you are used to knowing where your main document is, well, next.js does not expose this file, but you can override the default Document by adding a `_document.js` file in your pages folder.

```
touch pages/_document.js
```
We will be extending the `<Document />` and injecting the server side rendered styles into the `<head>`.

> To override that default behavior, you must create a file at `./pages/_document.js`, where you can extend the Document class.
> https://github.com/zeit/next.js/#custom-document

This is how a custom `_document.js` would look like, if we just rendered the page and nothing else:

```jsx
import Document, { Head, Main, NextScript } from 'next/document'

export default class MyDocument extends Document {
  static getInitialProps ({ renderPage }) {
    // Returns an object like: { html, head, errorHtml, chunks, styles }     
    return renderPage();
  }

  render () {    
    return (
      <html>
        <Head>
          <title>My page</title>
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    )
  }
}
```
This is how it looks like once we add SSR styled components.

```jsx
import Document, { Head, Main, NextScript } from 'next/document';
// Import styled components ServerStyleSheet
import { ServerStyleSheet } from 'styled-components';

export default class MyDocument extends Document {
  static getInitialProps({ renderPage }) {
    // Step 1: Create an instance of ServerStyleSheet
    const sheet = new ServerStyleSheet();

    // Step 2: Retrieve styles from components in the page
    const page = renderPage((App) => (props) =>
      sheet.collectStyles(<App {...props} />),
    );

    // Step 3: Extract the styles as <style> tags
    const styleTags = sheet.getStyleElement();

    // Step 4: Pass styleTags as a prop
    return { ...page, styleTags };
  }

  render() {
    return (
      <html>
        <Head>
          <title>My page</title>
          {/* Step 5: Output the styles in the head  */}
          {this.props.styleTags}
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    );
  }
}
```

Once this is done, restart your server and the error should go away, your `<h1>` tag should be red, and SSR styled components should work.

Thats it, so to recapitulate:

1. Create a project and install dependencies
2. Add scripts
3. Create a pages folder and a first page
4. Add styled components
5. Add a babel plugin and a custom `.babelrc` file
6. Create a custom `_document.js` file

As you can see, if you already have an existing next.js project, you only need to implement steps 4 to 6.

There is also a way to use plain `.css` files with next.js, I will be writing a guide on how to set it up soon.

## Resources

* [Next.js docs](https://nextjs.org/docs/#setup)
* [JavaScript Ramblings](https://jsramblings.com)

*This post was originally posted on my [website](https://www.adrianprieto.com/next-js-styled-components-the-really-simple-guide-%E2%96%B2-%F0%9F%92%85/) on 06/26/2018.*