Integrar Styled-Components a un proyecto NextJs con TypeScript

axelvaldez13

Axel Valdez

Posted on September 20, 2021

Integrar Styled-Components a un proyecto NextJs con TypeScript

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.

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

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

module.exports = {
  presets: ['next/babel'],
  plugins: [['styled-components', { ssr: true }]]
}
Enter fullscreen mode Exit fullscreen mode

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

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>
    )
  }
}
Enter fullscreen mode Exit fullscreen mode

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)

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

export default theme
Enter fullscreen mode Exit fullscreen mode

global.ts

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%;
  }
`
Enter fullscreen mode Exit fullscreen mode

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

/* 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 {}
}
Enter fullscreen mode Exit fullscreen mode

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.

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
Enter fullscreen mode Exit fullscreen mode

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!

💖 💪 🙅 🚩
axelvaldez13
Axel Valdez

Posted on September 20, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related