Integrar Styled-Components a un proyecto NextJs con TypeScript
Tags: nextjs, styledcomponents, typescript
Published: 2021-09-20 20:48:07

Integrar Styled Components a un proyecto Next.Js puede ser un tramite medio molesto pero con este tutorial a la criolla lo vas hacer en un toque y sin preocupaciones. 

**1- Tenemos que instalar nuestras dependencias de styled al igual que los types del mismo.**

```jsx
yarn add styled-components
yarn add @types/styled-components -D
```


**2- Creamos un archivo babel.config.js y vamos a copiar este código**

```jsx
module.exports = {
  presets: ['next/babel'],
  plugins: [['styled-components', { ssr: true }]]
}
```

**3- Vamos a crear varios archivos ts/tsx y, si podemos, mantenemos las carpetas en este orden**

- src
    - styles
        - global.ts
        - style.d.ts
        - theme.ts
    - pages
        - _document.tsx
        - _app.tsx


En el archivo **_document.ts** escribimos el siguiente código

```tsx
import React from 'react'
import Document, {
  DocumentContext,
  DocumentInitialProps,
  Html,
  Head,
  Main,
  NextScript
} from 'next/document'
import { ServerStyleSheet } from 'styled-components'

export default class MyDocument extends Document {
  static async getInitialProps(
    ctx: DocumentContext
  ): Promise<DocumentInitialProps> {
    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(): JSX.Element {
    return (
      <Html lang="en"> // o es dependiendo su idioma
        <Head>
			// aca irian los links y metas 
              // que adjuntamos en el head

          <meta charSet="utf-8" />
          <link rel="preload" href="https://fonts.googleapis.com/" />
          <link
            rel="stylesheet" 
            href="https://fonts.googleapis.com/css2?family=Josefin+Sans:wght@100;400&display=swap"
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}
```


Una vez hecho eso empezamos a definir nuestro theme **theme.ts** y theme global **global.ts** 

**theme.ts** (disclaimer: esto es a elección del proyecto obviamente, aca solo hardcodee el color, pero también podemos definir la tipografía entre otras cosas mas que forman parte de la User Interface)

```tsx
const theme = {
  colors: {
    background: '#202124',
    text: '#fff'
  }
}

export default theme
```

**global.ts**

```tsx
import { createGlobalStyle } from 'styled-components'

export default createGlobalStyle`
  *{
    margin: 0;
    padding:0;
    box-sizing:border-box
  }
  html {
    height: 100%;
  }
  body {
    color: ${props => props.theme.colors.text};
    background: ${props => props.theme.colors.background};
    font: 400 16px Josefin Sans, sans-serif;
    height: 100%;
  }
  h1 {
    font: 100 64px Josefin Sans, sans-serif;
  }
  #__next {
  height: 100%;
  }
`
```

Una vez hecho esto, tenemos que crear nuestro archivo **style.d.ts** para poder trabajar facilmente a la hora de leer nuestro theme

```tsx
/* eslint @typescript-eslint/no-empty-interface: "off" */
import 'styled-components'
import theme from './theme'

export type Theme = typeof theme

declare module 'styled-components' {
  export interface DefaultTheme extends Theme {}
}
```


Ya hechos la mayoria de nuestros archivos, procedemos a actualizar el archivo **_app.tsx** utilizando el ThemeProvider, el GlobalStyle definido en el global y nuestro theme. 

```tsx
import React from 'react'
import { AppProps } from 'next/app'
import GlobalStyle from '../styles/global'
import { ThemeProvider } from 'styled-components'
import theme from '../styles/theme'

const MyApp: React.FC<AppProps> = ({ Component, pageProps }) => {
  return (
    <ThemeProvider theme={theme}>
      <Component {...pageProps} />
      <GlobalStyle />
    </ThemeProvider>
  )
}

export default MyApp
```

Hecho todo esto ya podemos trabajar tranquilamente con styled components en NextJs con TypeScript. 💅🏼💅🏼

Happy Codinggg✨✨✨

Fuente donde me inspiré y seguí los pasos: https://www.youtube.com/watch?v=1nVUfZg2dSA&t=1780s

Suscribanse a Rocketseat, tienen muy buen contenido!