Styled-components in a Next.js project πŸ› οΈ

October 06, 2021

Lately, for personal projects, I have been using Next.js πŸš€

The developer experience is awesome πŸ€“

I also recently began learning the styled-components library.

A few days ago, I decided that I wanted to combine the two for a β€œdigital garden” that I have begun working on.

Next.js from Undraw

Just a Bit of Prep Involved πŸ‘·πŸ½β€β™‚οΈ

An easy way to begin a Next.js project is to use the following command in a terminal:

npx create-next-app <NameOfProject>

I happen to prefer working with the yarn package manager, which I have installed globally on my machine, so I run the following:

yarn create next-app <NameOfProject>

When I run the command yarn create next-app Next.js defaults to using a css-modules solution.

The Next.js command line tool will create a styles folder containing a Home.module.css file - which is imported into the pages/index.js file.

It will also create a globals.css file - which is imported into the pages/_app.js file.

The first step, after scaffolding the project with the CLI tool, is to cd into the root of the project and install the required packages for styled-components:

yarn add babel-plugin-styled-components styled-components

Then create a .babelrc file at the root - with the following contents:

// In .babelrc at the root of project

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

The next step is to create a _document.js file in the pages directory and paste in the following code:

// in pages/_document.js

import Document from "next/document"
import { ServerStyleSheet } from "styled-components"

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const sheet = new ServerStyleSheet()
    const originalRenderPage = ctx.renderPage

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: App => props => sheet.collectStyles(<App {...props} />),
        })

      const initialProps = await Document.getInitialProps(ctx)
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      }
    } finally {
      sheet.seal()
    }
  }
}

This code above can also be found at the styled-components example in the Next.js repo on GitHub.

Here is a link to the documentation πŸ₯‡


Choices After Setup δ·Ύ

Now that we have the the dependencies installed - .babelrc configured - and the provided code in a pages/_document.js file - we can begin using styled-components as we would in any Create React App project.

Of course, we no longer need Home.module.css file in the styles folder - so we can delete that and the related import inside index.js - along with some other cleanup of the boilerplate code.

We can choose to still use styles/globabls.css and keep the related import inside pages/_app.js - or we can simply delete those too and create our own global styles with the createGlobalStyle API from styled-components.

I have used both options and it is simply a matter of preference ⭐

Hope this article helps you when using styled-components with Next.js! πŸ’―

SourceCode from Undraw


Profile picture

A Programming Blog by John William Davis - Based in Seattle - I am interested in all things React, Node, Rust and Vim πŸ€“ Β  Follow me on Twitter Β βœ…