Cantinho do Bloguinho

Home
Sobre

Publicado em 21/11/2023

NextJS 14 + Styled Components - Carregando primeiro os estilos do CSS ao renderizar a página

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)

next.config.ts
1
/** @type {import('next').NextConfig} */
2
const nextConfig = {};
3
4
module.exports = nextConfig;
5
6
module.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:

registry.tsx
1
"use client";
2
3
import React, { useState } from "react";
4
import { useServerInsertedHTML } from "next/navigation";
5
import { ServerStyleSheet, StyleSheetManager } from "styled-components";
6
7
export 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.

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