SimpleNext.js

How to use styled components in Next.js apps

Cover Image for How to use styled components in Next.js apps
Marouane Reda
Marouane Reda
If you need to understand the basics of Next.js, i recommend this course. (Disclaimer : this is an affiliate link that may earn me a small commission, but with no extra cost to you if you choose to enroll)

While Next.js comes with styled-jsx as a built-in styling solution, you may be wishing to use styled-components to style your app. In this article we will see how to use styled components in an example Next.js app without hassle!

What is styled components

styled components is a tool meant to write CSS scoped to a single components and ensures it doesn't leak to other parts of our apps.

In the example below we style Title component and Wrapper component individually :

// Create a Title component that'll render an <h1> tag with some styles
const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

// Create a Wrapper component that'll render a <section> tag with some styles
const Wrapper = styled.section`
  padding: 4em;
  background: papayawhip;
`;

// Use Title and Wrapper like any other React component – except they're styled!
render(
  <Wrapper>
    <Title>
      Hello World!
    </Title>
  </Wrapper>
);

the main benefits of using styled components are :

  • Minimal generation of CSS
  • Automatic generation of class names avoids bugs such as duplication, misspelling, ...
  • Easier maintenance, upgrade or deletion of your CSS

How to use styled components in Next.js

We will see now how to use styled components in an example Next.js app :

Step1 : Install styled components

Open your terminal window and navigate to the place you want your Next.js project to locate in then running:

npx create-next-app next_styled

The name is totally up to you.

Navigate to the project root folder:

cd next_styled

Install styled components with the following command:

# with npm
npm install --save styled-components

#or with yarn
yarn add styled-components

Step 2 :Create a /pages directory and your first page.

From your project root directory:

mkdir pages && touch pages/index.js

Populate ./pages/index.js:

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

and then just run yarn dev and go to http://localhost:3000.

Step 3 : 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 :

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

Step 4 : create a custom _document.js file

Now we will create a pages/_document.js file, this file basically will override the default document and will be applied to all pages :

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()
    }
  }
}

now you can style your components, like in the index.js page :

import styled from 'styled-components';

or add a global style in your _app.js file :

```javascript
import { createGlobalStyle, ThemeProvider } from 'styled-components'

const GlobalStyle = createGlobalStyle`
  body {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }
`

const theme = {
  colors: {
    primary: '#0070f3',
  },
}

export default function App({ Component, pageProps }) {
  return (
    <>
      <GlobalStyle />
      <ThemeProvider theme={theme}>
        <Component {...pageProps} />
      </ThemeProvider>
    </>
  )
}


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

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