Using Next.js With Styled Components
1 min read

Using Next.js With Styled Components

I have been fiddling around with Next.js library for the past couple of months and it has been really fun so far.

Styled-Components is another great library I've started using in my production applications which has improved my development cycle.

Let's talk business now, Next.js is server-rendered library we will need to utilize Styled-Components server side rendering functions to get them working together.

Add styled-components package in your Next.js project:

yarn add styled-components

Now in the pages folder create a new file called _document.js and paste the following code snippet in it.

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

export default class MyCustomDocument extends Document {
  static getInitialProps ({ renderPage }) {
    const sheet = new ServerStyleSheet()
    const page = renderPage(App => props => sheet.collectStyles(<App {...props} />))
    const styleTags = sheet.getStyleElement()
    return { ...page, styleTags } // return styles collected
  }

  render () {
    return (
      <html>
        <Head>
          <title>My Page Title</title>
          {this.props.styleTags}
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    )
  }
}

Above code collects all the styles defined using styled-components in the application and return them to be populated as props before the page is rendered. Now inside render function the {this.props.styleTags} injects those collected styles in the head part of the page. Makes sense?

Moreover, If there is a need to apply global styles then import another function called injectGlobal and provide your styles before defining your custom document component.

import { ServerStyleSheet, injectGlobal } from "styled-components";

injectGlobal`
  html {
    font-size: 10px;
  }
  body {
    font-family: "Merriweather", serif;
    font-size: 1.6em;
    line-height: 1.6;
  }
`;

export default class MyCustomDocument extends Document {
//....

Next step is enabling Styled Components babel plugin

yarn add -D babel-plugin-styled-components

Then we will change our .babelrc to

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

That's it! I'm finding Next.js + Styled Component combination very productive and flexible. You can let me know your thoughts on this combo on twitter.