Frontend Serverless with React and GraphQL

Start at the beginning and work your way through this project. The code for each step as well as the finished project can be found in the Github repository.


2. 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.

bash

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.

.babelrc

{
"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.

pages/index.tsx

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.

pages/_document.tsx

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.