Getting Started with Styled-Components in Next.js

Jetly Sandita
JavaScript in Plain English
4 min readDec 31, 2020

--

You can write the actual CSS code to style your components. it also removes the mapping between component and style. for me, it’s better than CSS/SASS/SCSS. styled component

Photo by Roman Synkevych on Unsplash

I’m using an existing project from the previous article. we will make the pokemon list fancier with styled-components. you can clone here and use branch init.

1. Add a styled component to the project

yarn add styled-components

2. Make Header Component

The header for example and you can try others later with your way. create components folder on the root. inside folder component create folder Header.

Create file StyledHeader.js and create components with styled-components.

import styled from "styled-components";const StyledHeader = styled.div`padding: 0;margin: 0;box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.75);`;export default StyledHeader;

You can change for style with your style. with a background or anything else.

Because this file only for custom style, so we need to create index.jsx file for a component view like a general react component.

import StyledHeader from "./StyledHeader";export default function Header() {return (<StyledHeader><h1>Pokemon</h1></StyledHeader>);}

Let’s render the header component on file MainLayout.js

import Head from "next/head";import Header from "../components/Header";export default function MainLayout(props) {const { children } = props;return (<><Head><title>Pokemon</title></Head><Header /><div>{children}</div></>);}

It’s work but no style, why? because by default next js SSR. so we must make styled-components SSR too. let’s change _document.js.

import Document, { Html, Head, Main, NextScript } from "next/document";import { ServerStyleSheet } from "styled-components";const sheet = new ServerStyleSheet();class MyDocument extends Document {static async getInitialProps(ctx) {const sheet = new ServerStyleSheet();const originalRenderPage = ctx.renderPage;try {ctx.renderPage = () =>originalRenderPage({// useful for wrapping the whole react treeenhanceApp: (App) => (props) =>sheet.collectStyles(<><App {...props} /></>,),// useful for wrapping in a per-page basisenhanceComponent: (Component) => Component,});// Run the parent `getInitialProps`, it now includes the custom `renderPage`const initialProps = await Document.getInitialProps(ctx);return {...initialProps,styles: (<>{initialProps.styles}{sheet.getStyleElement()}</>),};} finally {sheet.seal();}}render() {return (<Html lang="en"><Head /><body><Main /><NextScript /></body></Html>);}}export default MyDocument;

Re-run and it’s work. but the body still has padding or margin.

Image By Jetly Sandita

3. Make a global style with styled-components

We need to change our body style. you can do this with global CSS with next js but it’s CSS/sass again, so don’t do that, and let’s change _document.js again with styled component (document here). you can add others like a font or anything.

import Document, { Html, Head, Main, NextScript } from "next/document";import { ServerStyleSheet, createGlobalStyle } from "styled-components";const GlobalStyle = createGlobalStyle`body {padding: 0;margin: 0;}`;class MyDocument extends Document {static async getInitialProps(ctx) {const sheet = new ServerStyleSheet();const originalRenderPage = ctx.renderPage;try {ctx.renderPage = () =>originalRenderPage({// useful for wrapping the whole react treeenhanceApp: (App) => (props) =>sheet.collectStyles(<><GlobalStyle /><App {...props} /></>,),// useful for wrapping in a per-page basisenhanceComponent: (Component) => Component,});// Run the parent `getInitialProps`, it now includes the custom `renderPage`const initialProps = await Document.getInitialProps(ctx);return {...initialProps,styles: (<>{initialProps.styles}{sheet.getStyleElement()}</>),};} finally {sheet.seal();}}render() {return (<Html lang="en"><Head /><body><Main /><NextScript /></body></Html>);}}export default MyDocument;

4. Change style with props

Styled components get props value when styling. so we can custom component style with props, like this.

import styled from "styled-components";const StyledHeader = styled.div`padding: 0;margin: 0;${(props) => props.height && `height: ${props.height}px;`};box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.75);`;export default StyledHeader;import StyledHeader from "./StyledHeader";export default function Header({ height }) {return (<StyledHeader height={height}><h1>Pokemon</h1></StyledHeader>);}
Image By Jetly Sandita

You can try something else like that. try font-size or anything you need to make fancier.

Next, I will share a theme and extend styled-components for the library components.

See Project Here

Comment below if you know any other ways, commend, or questions. Thank you :)

--

--