Archived course lesson
Add Styled Components
Objective: We will set up Styled Components into the base of our project so that we can utilize it across the app.
Our first stop now that we have a base Next.js instance running is to add styled components. This will allow us to write css in a more modular fashion where the styles will be scoped to a particular component. This works well with React’s modular style. We need to first add the styled-components package as well as a babel plugin for the package.
npm install --save styled-components
npm install --save-dev babel-plugin-styled-components
We need to now configure babel to use the styled-components plugin.
{
"presets": ["next/babel"],
"plugins": [["styled-components", { "ssr": true }]]
}
Now we can add our first style- in our case we will be creating a styled header. We can import styled components at the top of our file and then create a styled h1 component by simply using styled.h1 followed by a string with all of our styles. Then, instead of using the <h1> tag in our React component, we can use the <StyledHeader> component in the same way and it will create a h1 tag with the styles applied to that component.
import styled from 'styled-components';
const StyledHeader = styled.h1`
font-size: 2em;
text-align: left;
padding: 16px 16px;
`;
const Index = () => {
return (
<div>
<StyledHeader>Index Page</StyledHeader>
</div>
);
};
export default Index;
What we should see is that the component does indeed get styled, but there is flash of a second where it will show the unstyled text. We can fix this by extending our <Document /> component by injecting our styles into the head of or page. We do this by creating a _document.tsx in our pages folder which allows us to overwrite the base document component which is there by default.
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();
}
}
}
Once we finish, we should see that after we reload our page, the styled <h1> shows up immediately without a flash of bad styles and we should also see a favicon and title appear in our brower’s tab. If you don’t see this immediately, restart your web server by pressing ctrl+c and start it up again to make sure the changes load.