DEV Community

adambaialiev
adambaialiev

Posted on

How to add Styled Components to Next.js project using TypeScript

Want to use styled components in your Next.js project? Also using TypeScript?

Here are the steps we need to do:

  1. Add the styled components library with types
  2. Add the special babel plugin
  3. Create _document.tsx and _app.tsx files
  4. Create styled.d.ts declaration file.

Add the styled components library with types

Run

yarn add styled-components
yarn add @types/styled-components
Enter fullscreen mode Exit fullscreen mode

Add the special babel plugin

yarn add --dev babel-plugin-styled-components
Enter fullscreen mode Exit fullscreen mode

Create .babelrc file with the following:

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

Create _document.tsx and _app.tsx files

Create in pages/_document.tsx file

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();
    }
  }
  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Create pages/_app.tsx and paste the following:

import { createGlobalStyle, ThemeProvider } from "styled-components";

const GlobalStyle = createGlobalStyle`
  body {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }
  * {
    font-family: 'Open Sans', sans-serif;
  }
`;

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

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

Create styled.d.ts declaration file.

Create a declarations file for TypeScript in the project root. Let's name it styled.d.ts

import "styled-components";

declare module "styled-components" {
  export interface DefaultTheme {
    colors: {
      primary: string;
    };
  }
}
Enter fullscreen mode Exit fullscreen mode

So if we want to describe the shape of our Theme, we can do it here.

Use the library

Rename index.js to index.tsx, delete everything and paste the following:

import React from "react";
import styled from "styled-components";

const Title = styled.h1`
  font-size: 50px;
  color: ${({ theme }) => theme.colors.primary};
`;

const Home: React.FC = () => {
  return <Title />;
};

export default Home;
Enter fullscreen mode Exit fullscreen mode

That's it! You can now use the styled-components in Next.js with TypeScript.

Top comments (2)

Collapse
 
oraimbaud profile image
Olivier Raimbaud

You should also type ctx: DocumentContext

Source

Collapse
 
orololuwa profile image
Orololuwa

Must it be done with typescript?