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.