Using styled components with next.js 12 and typescript in 2022
Tags: nextjs, react, webdev, typescript
Published: 2022-03-07 17:42:55

In this article, I will show how you can use styled-components in next.js 12 along with typescript.

----
### Benefits:-
-  We can use normal css syntax, instead of using css-in-js method. _In order to set background color, we write `background-color:red` in plain css instead of using css-in-js method(annoying) `backgroundColor="red"`._
-  If you are a fan of sass(scss) like me, we can use sass like syntax inside the component.
-  Documentation is also pretty good.
-  Output size is small.



---
> #### Project Repo:- https://github.com/Sumukha210/tesla-clone

---
### Installing Next.js along with other dependencies,
  
``` bash
npx create-next-app@latest --typescript
```
#### or

``` shell
yarn create next-app --typescript 
```
then add these packages,
``` bash
yarn add styled-components
```

``` bash
yarn add -D @types/styled-components
``` 
-----
### Configuring Styled components for Next.js
 > You can skip this part if you are using plain React.js 

#### If you are Next.js 12, then you can just use this code, in `next.config.js`,

```tsx
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: false,
  compiler: {
    styledComponents: true,
  },
};

module.exports = nextConfig;
```

#### In `_document.tsx` file(inside pages folder), use this method if you are not using Next.js 12 

```tsx
import Document, { DocumentContext } from "next/document";
import { ServerStyleSheet } from "styled-components";

export default class MyDocument extends Document {
  static async getInitialProps(ctx: DocumentContext) {
    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();
    }
  }
}
```
----
### _Now we can get started to use styled components along with next js and typescript_
---

#### Creating a Button component

``` tsx

const MyCustomBtn = () => <Button darkBtn={false}>Custom Btn Button</Button>;

// Creating Simple button with props, checkout button component in elements folder for more advanced stuff about button
type buttonProps = {
  active?: boolean; // making this props optional
  darkBtn: boolean;
};

const Button = styled.button<buttonProps>`
  background-color: ${({ darkBtn }) =>
    darkBtn
      ? "black"
      : "cyan"}; // i am destructing here, instead of using as prop.darkBtn
  padding: 1rem 2rem;
  font-size: 1.2rem;
  border: none;

  &:hover {
    background: rebeccapurple;
  }


  /* if you want to place multiple lines of css, you can import {css}  */
  ${({ active }) =>
    active &&
    css`
      border: 2px solid gold;
      background-color: darkcyan;
      color: white;
    `}
`;

```
----

#### Creating a Container Component, using scss like syntax inside the component,
 
``` tsx

const MyContainer: React.FC = ({ children }) => (
  <Container>
    <div className="content">
      <ul>
        <li>First list</li>
        <li>second list</li>
        <li>third list</li>
        <li>fourth list</li>
      </ul>
      {children}
    </div>
  </Container>
);

const Container = styled.div`
  width: 80%;

  .content {
    padding: 2rem;

    ul {
      margin-bottom: 5rem;
      li {
        &:not(:last-child) {
          margin-bottom: 0.5rem;
        }
      }
    }
  }
`;
```
### Final Code:-
```tsx
import React from "react";
import styled, { css } from "styled-components";

const StyledComponents = () => {
  return (
    <MyContainer>
      <MyCustomBtn />
    </MyContainer>
  );
};

export default StyledComponents;

const MyCustomBtn = () => <Button darkBtn={false}>Custom Btn Button</Button>;

// Creating Simple button with props, checkout button component in elements folder for more advanced stuff about button
type buttonProps = {
  active?: boolean; // making this props optional
  darkBtn: boolean;
};

const Button = styled.button<buttonProps>`
  background-color: ${({ darkBtn }) =>
    darkBtn
      ? "black"
      : "cyan"}; // i am destructing here, instead of using as prop.darkBtn
  padding: 1rem 2rem;
  font-size: 1.2rem;
  border: none;

  &:hover {
    background: rebeccapurple;
  }

  /* if you want to place multiple lines of css, you can import {css}  */
  ${({ active }) =>
    active &&
    css`
      border: 2px solid gold;
      background-color: darkcyan;
      color: white;
    `}
`;

const MyContainer: React.FC = ({ children }) => (
  <Container>
    <div className="content">
      <ul>
        <li>First list</li>
        <li>second list</li>
        <li>third list</li>
        <li>fourth list</li>
      </ul>
      {children}
    </div>
  </Container>
);

const Container = styled.div`
  width: 80%;

  .content {
    padding: 2rem;

    ul {
      margin-bottom: 5rem;
      li {
        &:not(:last-child) {
          margin-bottom: 0.5rem;
        }
      }
    }
  }
`;
```

### Final output:- 
![Code output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zitoi1kn5fdlb7iw2ud2.png)