Esse é um tutorial que funciona no NextJS (v14.0.3) e também na versão mais recente do Styled-Components (v6.1.1)
Um dos típicos erros que enfrentamos ao estilizar uma página no framework NextJS é apresentar um "erro" (não necessariamente um erro e sim uma aparente falta de estilização) ao abrir a página pela primeira vez. Esse tipo de erro ocorre porque o NextJS possui uma arquitetura que divide o seu código em um modo cliente e modo servidor .
- O modo servidor se refere ao navegador no dispositivo do usuário que envia uma solicitação a um servidor para retornar algo (no nosso caso uma página web).
- O modo cliente se refere a um computador em um data center que armazena o código do seu aplicativo, como um site. Esse servidor recebe solicitações de um cliente e envia de volta uma resposta.
Já que destrinchamos essa longa parte, vamos realmente ao que interessa.
Para resolver esse problema basta modificar o arquivo padrão do NextJS:
next.config.js
ou
next.config.ts
. Agora verifique a linha 10 (compiler)
1/** @type {import('next').NextConfig} */2const nextConfig = {};3
4module.exports = nextConfig;5
6module.exports = {7 images: {8 domains: ["mks-sistemas.nyc3.digitaloceanspaces.com", "i.ibb.co"],9 },10 compiler: {11 styledComponents: true,12 },13};
O compiler:
diz para o NextJS compilar o seu código
utilizando o StyledComponents: true
. O arquivo
next.config.js
ou next.config.ts
é usado pelo servidor
NextJS, ou seja, é através desse arquivo que o seu código irá fazer a comunicação
com o servidor, então, ele irá carregar os
estilos CSS do Styled-Components
renderizados no lado do servidor.
Mas porquê que eu tenho que fazer todo esse processo? Porque por padrão o CSS é renderizado ao lado do cliente para evitar sobrecarregar o servidor com muitas informações, mas, utilizamos o framework NextJS que pré-renderiza todas as páginas no lado servidor e por isso que em um primeiro momentos a página carrega o conteúdo sem estilização.
No entanto, temos uma parte excelente em que o Styled Components tem a vantagem de rodar (renderizar) no lado do servidor de forma simultânea com o cliente, renderizando somente o necessário (que nesse caso você é quem irá configurar quais os elementos serão estilizados) e isso é muito mais eficiente que o CSS normal.
Também temos que criar um arquivo raiz chamado de
registry.js
ou
registry.tsx
da seguinte maneira:
1"use client";2
3import React, { useState } from "react";4import { useServerInsertedHTML } from "next/navigation";5import { ServerStyleSheet, StyleSheetManager } from "styled-components";6
7export default function StyledComponentsRegistry({8 children,9}: {10 children: React.ReactNode;11}) {12 const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet());13
14 useServerInsertedHTML(() => {15 const styles = styledComponentsStyleSheet.getStyleElement();16 styledComponentsStyleSheet.instance.clearTag();17 return <>{styles}</>;18 });19
20 if (typeof window !== "undefined") return <>{children}</>;21
22 return (23 <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>24 {children}25 </StyleSheetManager>26 );27}
Este código é um módulo para registrar e gerenciar componentes estilizados em uma aplicação React. Ele exporta uma função padrão chamada StyledComponentsRegistry que recebe a propriedade children como entrada.
React
para criar componentes ReactuseState
do React para gerenciar estado em componentes
funcionais
useServerInsertedHTML
de
next/navigation
para gerenciar HTML renderizado no servidor
ServerStyleSheet
de
styled-components
para criar uma folha de estilo no lado do servidor
StyleSheetManager
de
styled-components
para gerenciar as folhas de estilos
Dentro da função StyledComponentsRegistry, ele inicializa uma variável de estado styledComponentsStyleSheet usando o gancho useState. O valor inicial é uma nova instância de ServerStyleSheet.
O código então usa o gancho useServerInsertedHTML para inserir o elemento de estilo no HTML renderizado no servidor. Ele recupera o elemento de estilo da instância styledComponentsStyleSheet usando getStyleElement(), limpa a tag de estilo usando clearTag() , e retorna os estilos como um fragmento JSX.
Em seguida, o código verifica se o código está sendo executado no lado do cliente, verificando se o objeto window está definido. Se estiver, ele retorna a propriedade children sem nenhuma modificação.
Se o código estiver sendo executado no lado do servidor, ele envolve a propriedade children com um componente StyleSheetManager e passa styledComponentsStyleSheet.instance como a propriedade sheet.
No geral, este código configura um registro para gerenciar componentes estilizados em uma aplicação React, garantindo que os estilos sejam renderizados corretamente tanto no servidor quanto no cliente