Next.JS: aplicações fullstack com super poderes

Next.JS: aplicações fullstack com super poderes

Se você tem algum tipo de contato com desenvolvimento front-end, provavelmente já ouviu falar de React e Next.js.

Enquanto o React é uma das mais famosas bibliotecas focadas no desenvolvimento de interfaces com as pessoas usuárias, o Next.js é um framework que estende as funcionalidades do React e nos permite construir aplicações fullstack.

Nesse artigo, vamos explorar o universo do Next.js: entender como ele pode facilitar o desenvolvimento de aplicações e resolver vários problemas conhecidos do React.

Além disso, nós vamos percorrer os pontos fortes desse framework, suas principais funcionalidades e ferramentas.

A diferença entre biblioteca e framework é como a diferença entre um kit de ferramentas e um plano de construção. Com uma biblioteca, você tem acesso a uma variedade de ferramentas que pode escolher e usar conforme a necessidade, mantendo o controle total sobre como e quando utilizá-las em seu projeto. Já um framework, é como um plano detalhado para um projeto, guiando não só com as ferramentas, mas também com as regras e estruturas sobre como deve ser construído. Enquanto a biblioteca te dá liberdade e flexibilidade, o framework oferece direção e ordem, ajudando a moldar todo o processo de desenvolvimento.

O que é Next.js?

Next.js é um framework para quem usa React e quer dar um passo adiante. Ele é como um kit avançado para construir sites e aplicações web.

Se você já sabe usar o React para criar interfaces de usuário, o Next.js te ajuda a fazer mais, como melhorar o desempenho da sua página na internet.

Ele faz isso permitindo que partes do seu site sejam geradas antes, no servidor, ao invés de tudo ser feito no navegador do usuário. Isso é ótimo para que seu site apareça mais rápido nas buscas do Google, por exemplo.

Além disso, o Next.js torna mais fácil criar e organizar as diferentes páginas do seu site. É como ter uma ferramenta que não só ajuda a montar os blocos, mas também organiza onde cada bloco deve ir.

Banner promocional da Alura, com um design futurista em tons de azul, apresentando o texto

Por que usar Next.js?

Imagine que você está construindo um website ou uma aplicação web e quer que ela seja não só bonita e funcional, mas também rápida e facilmente encontrada na internet.

É aqui que entra o Next.js, como um grande aliado. Vamos pensar em alguns cenários em que ele brilha:

  • Seu site precisa carregar rapidamente: No mundo digital de hoje, cada segundo conta. Com o Next.js, partes do seu site são preparadas antecipadamente no servidor. Isso significa que, quando alguém visita seu site, ele aparece quase instantaneamente. É como ter um restaurante em que parte da refeição já está pronta antes mesmo do cliente pedir.

  • Você quer aparecer bem posicionado no Google: Para sites que precisam de boa visibilidade em motores de busca, o Next.js é um verdadeiro herói. Ele ajuda seu site a ser mais “amigável” para o Google, o que pode significar uma posição melhor nos resultados de busca.

  • Você vai criar muitas páginas: Se você está planejando um site com várias páginas, o Next.js ajuda a organizá-las de forma eficiente. É como ter um assistente que não só ajuda a construir cada sala de uma grande casa, mas também se certifica de que todas estão bem conectadas.

  • Você quer flexibilidade com performance: Com o Next.js, você consegue essa rara combinação de flexibilidade no desenvolvimento e eficiência no desempenho do site. É como dirigir um carro que é fácil de manobrar, mas também rápido na estrada.

O Next.js é perfeito para quando você quer que seu site ou aplicação web se destaque, tanto em velocidade quanto em acessibilidade, sem sacrificar a beleza e funcionalidade do design.

É uma ferramenta que empodera, permitindo que você construa não apenas um site, mas uma experiência web completa e refinada.

Benefícios do Next.js

Então, de maneira resumida, esses são os principais benefícios do Next.js:

Upgrade para o React

Imagine o Next.js como um upgrade para o React. Enquanto no React você cria interfaces incríveis, o Next.js eleva isso para um outro nível com a renderização no lado do servidor.

Pense na diferença entre preparar um prato na hora e ter um prato pré-preparado e pronto para servir. Isso faz com que seu site carregue rapidamente, quase como um mágico que faz aparecer o site instantaneamente na tela do usuário.

Melhoria na visibilidade dos sites nos sites de busca

No quesito SEO, o Next.js brilha intensamente. Se o React é como uma loja em uma rua secundária, o Next.js move essa loja para a avenida principal.

Ele melhora a visibilidade do seu site nos motores de busca, tornando-o mais acessível para o público.

Maior flexibilidade de desenvolvimento

Quanto à flexibilidade de desenvolvimento, o Next.js adiciona especiarias ao prato básico do React. Você mantém a liberdade de criar com React, mas com recursos extras que otimizam o processo. É como cozinhar com temperos exóticos que realçam o sabor.

Roteamento automático

Um dos trunfos do Next.js é o roteamento. No React, você pode gerenciar rotas com o React Router, mas o Next.js simplifica esse processo. É como ter um GPS que não só te dá o caminho, mas também sugere as melhores rotas automaticamente.

Maior agilidade no desenvolvimento

O Next.js também acelera o desenvolvimento. No React, você pode se perder em configurações e detalhes técnicos, mas o Next.js automatiza muitas dessas tarefas. Ele cuida dos detalhes enquanto você se concentra na criação.

O suporte a conteúdo estático e dinâmico no Next.js é mais integrado e eficiente do que no React puro. Se no React você tem que fazer malabarismos entre esses diferentes tipos de conteúdo, no Next.js é como ter uma ferramenta que se adapta automaticamente às suas necessidades.

Vale reforçar: o Next.js não substitui o React; ele o potencializa. Ele oferece ferramentas e funcionalidades que tornam a criação de sites e aplicações web mais rápidas, acessíveis e eficientes, simplificando muitos dos processos que, no React, demandariam soluções adicionais ou mais complexas.

Documentação do Next.js

https://media1.tenor.com/m/LPwQVB6FAf8AAAAC/indiana-jones-hmm.gif

Explorar a documentação do Next.js é como embarcar em uma jornada de aprendizado bem estruturada e recheada de informações úteis.

A documentação foi cuidadosamente elaborada para ser amigável tanto para iniciantes quanto para pessoas desenvolvedoras experientes.

A documentação do Next.js oferece um conteúdo aprimorado, com novas seções explicando conceitos fundamentais e recursos.

Ela foi dividida em múltiplas páginas, cada uma focando em um conceito específico, facilitando a localização rápida do conteúdo relevante.

O layout foi atualizado para melhor organizar o conteúdo, concentrando-se nas características e conceitos essenciais, separando os recursos avançados dos básicos.

Um recurso particularmente útil é a busca 'fuzzy' no novo menu lateral, permitindo uma pesquisa rápida por toda a documentação. Isso ajuda a manter a sensação de uma página única, mesmo com a documentação sendo dividida em múltiplas seções.

Além disso, a seção de referência da API é uma adição frequentemente solicitada, fornecendo informações detalhadas sobre parâmetros, funções e muito mais.

Anteriormente, essas referências estavam entrelaçadas com a explicação do recurso, mas agora têm um espaço dedicado.

A documentação do Next.js também é sincronizada com novos recursos, uma vez que o conteúdo ainda reside no repositório do GitHub do Next.js. Isso garante que as informações estejam sempre atualizadas com os lançamentos mais recentes.

Para quem está começando, o site nextjs.org/learn oferece uma experiência de aprendizado interativa, guiando você através de muitos recursos que o Next.js oferece por padrão.

As lições são projetadas para reforçar seu conhecimento e estão disponíveis sem a necessidade de login, permitindo que você comece a aprender imediatamente.

A documentação do Next.js é um recurso dinâmico, com melhorias e adições contínuas baseadas no feedback dos usuários.

Isso inclui novas seções sobre conceitos tanto de alto quanto de baixo nível que o Next.js ajuda a gerenciar.

Para mais detalhes, você pode explorar a documentação diretamente no site oficial do Next.js.

Next.js: rotas (router)

Vamos começar com o Page Router, o sistema clássico de roteamento do Next.js, e depois mergulhar no moderno App Router.

  • Pages Router: o clássico

Pense no Pages Router como uma biblioteca antiga, onde cada livro é uma página da sua aplicação.

Em versões mais antigas do Next.js, cada página do seu site era um arquivo em uma pasta especial chamada pages. O nome do arquivo determinava o caminho da URL.

Por exemplo, um arquivo chamado sobre.js resultava em uma rota /sobre no seu site. Simples e direto.

Este sistema era como um mapa claro e fácil de seguir. Cada página era um destino, e o nome do arquivo era a sinalização. Você não precisava configurar rotas explicitamente, o Next.js fazia isso automaticamente para você, baseando-se na estrutura de arquivos.

Era uma abordagem muito eficiente, mas com algumas limitações, especialmente quando se tratava de rotas mais complexas ou dinâmicas.

  • App Router: A evolução

O App Router foi construído em cima dos Server Side Components (componentes do lado do servidor) do React.

Isso significa que agora temos suporte a layouts compartilhados, roteamento aninhado, estados de carregamento, tratamento de erros e muito mais.

Esse roteador funciona em um novo diretório chamado "app" (daí o nome "App Router").

Se você está migrando do Page Router para o App Router, esse diretório "app" trabalha em conjunto com o diretório "pages", permitindo uma adoção gradativa.

Assim, você pode incorporar gradualmente as novas funcionalidades em algumas rotas da sua aplicação, enquanto mantém outras rotas no diretório "pages", conforme estava acostumado.

Uma dica importante: o App Router tem prioridade sobre o Page Router. Por isso, tenha atenção para não criar rotas nos dois diretórios que levam ao mesmo caminho URL. Fazendo isso, você vai receber um erro durante a compilação, para evitar conflitos.

Por padrão, os componentes dentro do diretório "app" são Server Components. Isso não só otimiza o desempenho, como também facilita a sua vida na hora de adotá-los. Ah, e não se esqueça: você ainda pode usar Client Components normalmente.

Roteamento é um assunto tão importante que eu escrevi o artigo Roteamento eficiente com Next.js: descobrindo o App Router focado nisso, com vários diagramas e ilustrações bacanas.

Como funciona a construção das páginas e rotas?

O App Router do Next.js, introduzido na versão 13, é uma nova abordagem para construir aplicações com componentes de servidor do React.

Ele introduz conceitos como layouts compartilhados, roteamento aninhado, estados de carregamento e tratamento de erros, oferecendo mais flexibilidade e controle do que o tradicional sistema de roteamento baseado em sistema de arquivos do Next.js.

Funcionamento básico

O App Router funciona através de um novo diretório chamado app, que trabalha em conjunto com o diretório pages.

Isso permite a adoção incremental do App Router em aplicações existentes. Você pode começar a usar o novo roteador em algumas rotas da sua aplicação, mantendo outras no sistema de rotas antigo.

É importante notar que o App Router tem prioridade sobre o Pages Router, e não é possível ter rotas que resolvam para o mesmo caminho URL nos dois sistemas.

Construção de rotas

No App Router, as pastas dentro do diretório app definem as rotas. Cada segmento de rota é mapeado para um segmento correspondente no caminho da URL.

Por exemplo, uma estrutura de pastas como app/dashboard/settings resultaria em uma rota /dashboard/settings.

Dentro dessas pastas, arquivos especiais como page.js, layout.js, loading.js e error.js definem a interface com o usuário e o comportamento para cada segmento da rota.

Componentes especiais

Os componentes especiais são:

  • layout.js: Define um layout compartilhado para um segmento e seus filhos.
  • page.js: Uma página única de uma rota e torna as rotas acessíveis publicamente.
  • loading.js: Componente que indica o carregamento para um segmento e seus filhos.
  • error.js: Página de erro para um segmento e seus filhos.
  • route.js: Endpoint de API no lado do servidor.

Características avançadas

O App Router também suporta padrões de roteamento avançados, como Rotas Paralelas e Interceptação de Rotas, permitindo a construção de interfaces mais ricas e complexas.

Por exemplo, Rotas Paralelas permitem mostrar duas ou mais páginas na mesma visualização, que podem ser navegadas independentemente.

Adoção e uso

O Next.js recomenda o uso do App Router para novas aplicações, devido à sua flexibilidade e aos recursos avançados que oferece.

Para aplicações existentes, a adoção pode ser feita de forma incremental.

Páginas e layouts no App Router

Quando falamos de páginas no App Router, estamos lidando com a essência da sua aplicação. Cada `page.js que você cria no diretório app representa uma parte única da sua história digital.

Por exemplo, um arquivo app/page.tsx seria a cena de abertura, a página inicial do seu site. Já um app/dashboard/page.tsx levaria os usuários para uma seção específica, como um painel de controle.

A imagem exibe uma representação conceitual da estrutura de diretórios de uma aplicação web à esquerda, com setas apontando para os caminhos de URL correspondentes à direita. Existem dois diretórios principais: "app" e "dashboard", cada um contendo um arquivo chamado "page.js". O "page.js" no diretório "app" está associado ao caminho de URL raiz "/", e o "page.js" no diretório "dashboard" está associado ao caminho de URL "/dashboard". No canto inferior direito, há um logotipo ou marca d'água que diz "alura". O estilo visual é moderno e técnico, frequentemente usado em documentações ou apresentações para explicar roteamento ou estrutura de websites.

Essas páginas são como as cenas principais do seu filme digital, cada uma com seu próprio papel e importância no enredo geral.

O Papel dos layouts

Agora, imagine os layouts como o cenário onde essas cenas se desenrolam. Um layout.js define o ambiente compartilhado para múltiplas páginas.

Por exemplo, um layout no app/dashboard/layout.tsx poderia incluir elementos comuns como cabeçalhos ou barras laterais que são constantes em todas as páginas do painel de controle.

A imagem mostra uma representação gráfica da estrutura de diretórios de um projeto de aplicação web. No diretório principal "app", há um subdiretório chamado "dashboard", que contém dois arquivos: "layout.js" (indicado por um ponto azul, sugerindo que é o arquivo atualmente selecionado ou em destaque) e "page.js". Além disso, há outro subdiretório dentro de "dashboard" chamado "settings", que também contém um arquivo "page.js". Do lado esquerdo da imagem, há uma braçadeira com setas apontando para o diretório "dashboard", possivelmente indicando uma relação de herança ou uma rota de navegação no projeto.

Esses layouts são como o palco que se mantém, mesmo quando as cenas (páginas) mudam. Eles não só dão consistência visual, mas também mantêm o estado da aplicação entre as mudanças de página.

Root Layout

O Root Layout, definido no topo do diretório app, é como a base de todo o seu projeto. Ele se estende por todas as rotas da sua aplicação.

Pense nele como o alicerce da sua construção digital. Ele deve conter as tags e, já que o Next.js não as cria automaticamente.


export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

Interação entre páginas e layouts

No App Router, as páginas e layouts interagem de uma forma dinâmica. Os layouts podem ser aninhados, com cada um envolvendo suas páginas e layouts filhos, criando uma estrutura hierárquica que reflete a arquitetura da sua aplicação.

A imagem mostra uma representação visual da estrutura de diretórios de uma aplicação web, com o diretório principal "app" no topo. Dentro de "app", existem dois arquivos: "layout.js" e "page.js". Há também um subdiretório chamado "dashboard" que contém outros dois arquivos: "layout.js" (destacado com um ponto azul, sugerindo que é o arquivo atualmente em foco) e "page.js". No lado esquerdo, uma braçadeira com três setas aponta para o subdiretório "dashboard", o que pode indicar uma relação de importância ou foco dentro da estrutura do projeto. A imagem tem um estilo técnico e moderno, típico de diagramas usados para explicar estruturas de diretórios em documentações de desenvolvimento de software.

Templates: uma alternativa aos layouts

Os templates no App Router funcionam de maneira semelhante aos layouts, mas com um comportamento distinto. Eles são recriados a cada navegação, não mantendo o estado como os layouts fazem.

Isso é útil em situações onde você precisa de um comportamento específico a cada mudança de página.


export default function Template({ children }: { children: React.ReactNode }) {
  return <div>{children}</div>
}
A imagem exibe uma estrutura de diretórios de uma aplicação web com o diretório "app" destacado. Dentro deste diretório, há três arquivos: "layout.js", "template.js" (este último com um ponto azul ao lado, indicando que está selecionado ou em foco) e "page.js". O estilo visual é limpo e moderno, com um esquema de cores que vai do azul ao preto. Este tipo de representação é comumente utilizado em documentações técnicas para ilustrar a organização dos arquivos dentro de um projeto de software.

Em termos de aninhamento, o template.js é renderizado entre um layout e seus filhos. Assim:


<Layout>
  <Template key={routeParam}>{children}</Template>
</Layout>

Começando com Next.js e React

O Next.js é especialmente conhecido por sua capacidade de renderização no lado do servidor e geração de sites estáticos, o que pode ser um grande impulso para o SEO e o desempenho da sua aplicação.

Primeiros passos

Os primeiros passos no Next.js são:

  • Instalação: O primeiro passo é criar um novo projeto Next.js. Você pode fazer isso com um simples comando no terminal, mas não se preocupe com isso nesse momento que vamos entrar em detalhes sobre como uma aplicação Next é criada.

  • Estrutura do projeto: Ao explorar seu novo projeto Next.js, você notará algumas diferenças em relação ao React puro. Há uma pasta pages, onde cada arquivo JavaScript ou TypeScript representa uma rota da sua aplicação. É uma abordagem intuitiva e organizada.

  • Criando páginas: Para criar uma nova página, basta adicionar um novo arquivo na pasta apps. Por exemplo, um arquivo contato.js se torna automaticamente acessível em /contatos. Simples assim!

Dicas e truques

Mas para te ajudar nesse processo, aqui estão algumas dicas e truques:

  • Explore as API Routes: O Next.js permite que você crie endpoints de API diretamente no seu projeto, facilitando a construção de aplicações full-stack. Isso é feito através de arquivos na pasta pages/api.

  • CSS-in-JS e estilos globais: O Next.js suporta CSS-in-JS e a importação de arquivos CSS globais. É uma maneira elegante e eficiente de lidar com estilos na sua aplicação.

  • Pré-renderização e dados estáticos: O Next.js facilita a pré-renderização de páginas e o manuseio de dados estáticos, o que é ótimo para páginas que não precisam de dados dinâmicos constantemente atualizados.

Começando uma aplicação Next.js

Primeiramente, certifique-se de que você tem o Node.js na versão 18.17 ou mais recente instalado (essa é a versão mínima atual para o Next na versão 14. novas versões do Next podem requerer uma versão mais recente do Node).

O Next.js é compatível com macOS, Windows (incluindo WSL) e Linux. Então, vamos lá:

  • Instalação automática

Para criar um novo projeto Next.js, use o comando npx create-next-app@latest. Durante a instalação, você verá prompts como:

  • Nome do seu projeto? (Exemplo: my-app)
  • Deseja usar TypeScript? (Sim/Não)
  • Deseja usar ESLint? (Sim/Não)
  • Deseja usar Tailwind CSS? (Sim/Não)
  • Deseja usar o diretório src/? (Sim/Não)
  • Deseja usar o App Router? (Recomendado) (Sim/Não)
  • Deseja personalizar o alias de importação padrão (@/*)? (Sim/Não)
  • Qual alias de importação você gostaria de configurar? (Exemplo: @/*)

Após os prompts, o create-next-app criará uma pasta com o nome do seu projeto e instalará as dependências necessárias.

  • Instalação manual

Caso prefira, você pode criar manualmente um novo projeto Next.js. Instale os pacotes necessários com npm install next@latest react@latest react-dom@latest e configure os scripts necessários no seu package.json:

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  }
}

Esses scripts se referem aos diferentes estágios do desenvolvimento de uma aplicação:

  • dev: executa next dev para iniciar o Next.js no modo de desenvolvimento.
  • build: executa next build para construir a aplicação para uso em produção.
  • start: executa next start para iniciar um servidor de produção Next.js.
  • lint: executa next lint para configurar o ESLint integrado do Next.js.

Next.js: entendendo o file-system routing

O Next.js usa roteamento baseado em sistema de arquivos, o que significa que as rotas na sua aplicação são determinadas pela forma como você estrutura seus arquivos.

O diretório app

Para novas aplicações, recomenda-se usar o App Router. Ele permite usar os recursos mais recentes do React e é uma evolução do Pages Router baseado no feedback da comunidade.

Crie um diretório app, depois adicione um arquivo layout.tsx e page.tsx. Eles serão renderizados quando o usuário visitar a raiz da sua aplicação (/).

Estrutura do diretório app:

Crie um layout raiz dentro de app/layout.tsx com as tags e necessárias:


// app/layout.tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="pt-br">
      <body>{children}</body>
    </html>
  )
}

Em seguida, crie uma página inicial app/page.tsx com algum conteúdo inicial:


// app/page.tsx
export default function Page() {
  return <h1>Olá mundo, com Next.js e Alura!</h1>
}

Next.js API: como tratar dados vindos de uma API

No mundo do Next.js, o fetch ganha superpoderes. Ele é aprimorado para que você possa configurar o cache e a revalidação de dados em cada solicitação feita ao servidor.

Na prática, digamos que você está no arquivo app/page.tsx do seu projeto Next.js. Aqui, você pode usar o fetch com async/await de formas diversas: seja em Server Components, seja em Route Handlers ou mesmo em Server Actions.

É como ter uma ferramenta versátil que se adapta a diferentes cenários na sua aplicação. Assim:


// app/page.tsx
async function obterDados() {
  const res = await fetch('https://api.ecommerce.com/...')
  if (!res.ok) {
    throw new Error(Falha ao obter dados de api.ecommerce!')
  }
  return res.json()
}

export default async function Page() {
  const data = await obterDados()
  return <main></main>
}

Server Side Rendering

Imagine uma peça de teatro em que o cenário e as personagens são montados e preparados nos bastidores (o servidor) antes de serem apresentados ao público (o navegador do usuário). SSR funciona de maneira semelhante.

A imagem ilustra o processo de renderização do lado do servidor em um fluxo contínuo de ações. Inicia-se com a solicitação de um arquivo HTML pelo navegador a partir de um computador desktop e um dispositivo móvel. Em seguida, o servidor, representado por ícones de racks de servidores, processa os dados necessários e renderiza a aplicação web. Uma vez processado, o conteúdo da página torna-se imediatamente disponível para o usuário, exibido dentro de um monitor. Adicionalmente, eventos e DOMs virtuais (Document Object Model) são incorporados ao conteúdo e, finalmente, a aplicação web é completamente carregada e exibida numa interface de usuário pronta para uso no monitor. **Com SSR, a maior parte do trabalho de geração da página acontece no servidor** Quando um usuário solicita uma página, o servidor processa a requisição, prepara o HTML completo, incluindo conteúdo e estrutura, e então o envia ao navegador do usuário.

Isso significa que o usuário vê a página inteira de uma só vez, assim que ela é carregada.

As principais vantagens disso são:

  • Melhor desempenho inicial e mais rápido carregamento da página, especialmente útil para SEO.
  • O conteúdo é visível mesmo se o JavaScript estiver desativado no navegador do usuário.

Entre as desvantagens estão:

  • Pode ser mais exigente em termos de recursos do servidor, especialmente com muitos usuários acessando simultaneamente.
  • Cada mudança ou interação na página pode exigir um carregamento completo da página.

Client Side Rendering (CSR)

Agora, imagine um palco onde apenas o esqueleto do cenário é montado inicialmente. À medida que a peça avança, mais elementos são trazidos para o palco. Isso é semelhante ao CSR.

A imagem descreve o processo de "Client side rendering" ou renderização do lado do cliente. O navegador inicia o processo solicitando um arquivo HTML ao servidor, que responde rapidamente com um documento HTML e links para CSS, JavaScript, etc. Enquanto isso, é exibida uma página em branco ou com animação de loading para o usuário, significando que o navegador está executando o JavaScript e o restante do conteúdo ainda está sendo carregado. Gradualmente, os dados necessários são recuperados, visualizações são geradas e integradas ao Document Object Model (DOM). Finalmente, a aplicação web é carregada completamente e se torna pronta para uso, apresentando a interface final ao usuário. A imagem possui um esquema de cores azul e branco e apresenta um layout organizado para demonstrar cada etapa do processo, destinada a fins educativos para explicar a renderização no desenvolvimento web.

Com CSR, o navegador do usuário recebe apenas um esqueleto básico da página do servidor. O conteúdo e a estrutura da página são gerados e renderizados no lado do cliente (navegador) usando JavaScript.

Isso significa que a página é construída progressivamente no navegador do usuário.

As vantagens disso são:

  • Menos carga no servidor, pois a maior parte do processamento ocorre no cliente.
  • Após o carregamento inicial, as interações e mudanças na página são geralmente mais rápidas, pois não requerem recarregamentos completos.

E as desvantagens:

  • O carregamento inicial pode ser mais lento, pois o navegador precisa baixar, interpretar e executar o JavaScript antes de renderizar a página.
  • Problemas potenciais com SEO, já que os motores de busca podem ter dificuldades em indexar conteúdo que é carregado dinamicamente.

Como funciona na prática o Server Side Rendering em Next.js

Imagine que você está em uma cozinha de um restaurante prestes a preparar um prato especial. Essa cozinha é o SSR no Next.js, e o prato especial é a sua página web.

O preparo do prato (renderização no servidor)

Quando um cliente pede um prato (quando alguém acessa sua página), ao invés de mandar os ingredientes separadamente para eles montarem o prato (o que seria o Client Side Rendering), o SSR prepara o prato completo na cozinha (servidor).

A imagem apresenta um fluxograma narrando o processo de SSR, ou renderização do lado do servidor, em um fundo azul escuro com texto e ícones em azul mais claro. Começa com o usuário solicitando um website, representado por um ícone de globo terrestre. Em seguida, o servidor cria arquivos HTML prontos, indicado por um ícone de servidor. O navegador então renderiza o HTML, mas ele não é interativo neste ponto, simbolizado por um monitor. O passo seguinte mostra o navegador baixando o JavaScript, representado por uma seta apontando para baixo e para o monitor. Posteriormente, o navegador executa o JavaScript, ilustrado por um globo e uma seta entrando no monitor. Finalmente, o navegador fica totalmente interativo, o que é demonstrado pelo monitor exibindo uma interface gráfica de usuário. Acima de todo o processo, está o título "SSR (Server-side rendering)".

Isso significa que quando o prato chega à mesa do cliente (o navegador do usuário), ele está pronto para ser apreciado, com todos os sabores (conteúdos) e apresentação (estilos CSS) já no lugar.

E como isso funciona no Next.js?

Por padrão, o Next.js já tem essa cozinha montada pra você. Quando você cria uma página, o Next.js automaticamente prepara tudo no servidor.

Ele divide o trabalho em partes (segmentos de rotas) e, se necessário, ainda usa técnicas como a transmissão (streaming) para servir o prato (página) ainda mais rápido.

Mas e a interatividade?

A imagem apresenta dois conceitos principais do processo de pré-renderização utilizando Next.js, ilustrados lado a lado contra um fundo azul escuro. No lado esquerdo, sob o título "Carregamento Inicial", um monitor mostra uma página com HTML pré-renderizado já exibido. Isto indica que o conteúdo estático é carregado primeiro para o usuário. Uma seta rotulada "JS carrega" aponta para a direita, ligando ao segundo conceito no lado direito da imagem, intitulado "Hydration (hidratação)". Aqui, outro monitor exibe a mesma página, mas enfatiza que os componentes React são inicializados e o aplicativo se torna interativo. Uma nota abaixo explica que se o aplicativo tem componentes interativos como "<Link />", eles estarão ativos após o carregamento do JavaScript. Acima de ambos os conceitos, há linhas diagonais e o título "Pre-rendering (Using Next.js)", ressaltando o uso do framework Next.js no processo de pré-renderização.

Depois que o prato é entregue, o Next.js começa a trabalhar nos detalhes finais, como temperos que o cliente pode adicionar à vontade.

Isso é a "hidratação" no lado do cliente, onde o Next.js ativa os scripts JavaScript para tornar a página interativa.

Server Components

No Next.js, usar Server Components (Componentes de Servidor) é o padrão quando você trabalha com o App Router.

Isso significa que a renderização do servidor é aplicada automaticamente, sem necessidade de configuração adicional.

A imagem representa uma interface de usuário de um aplicativo web, demonstrando a distinção entre componentes do cliente e do servidor. No topo, há uma barra de navegação marcada com pontos coloridos típicos de um navegador web e um campo de busca à direita. À esquerda, observa-se uma barra lateral contendo várias linhas que podem representar menu ou opções de navegação. O centro da imagem é dominado por uma área principal, que inclui conteúdos de mídia como imagens e textos, destacados por contornos pontilhados, com botões secundários representados por retângulos. Abaixo, uma legenda distingue "Client Components" (Componentes de Cliente), indicados pela cor azul, dos "Server Components" (Componentes de Servidor), indicados pela cor roxa. Esta imagem é utilizada para ilustrar conceitos de programação e arquitetura de software, especificamente a separação de responsabilidades no desenvolvimento de aplicações web.

Se for preciso, você tem a opção de usar Client Components (Componentes de Cliente), que oferecem mais flexibilidade para casos específicos.

Essa abordagem padrão com o App Router facilita a implementação de SSR, otimizando a performance e a experiência do usuário.

Static Site Generation

Na Renderização Estática do Next.js, as páginas são processadas no momento da construção do site ou após a atualização dos dados.

Isso significa que o conteúdo da página não muda com cada visita ou usuário, pois já está pronto e armazenado.

Pense em uma página de blog ou de produto: uma vez criada, ela não precisa de ajustes personalizados para cada visitante.

A imagem mostra um esquema explicativo do processo de geração estática em aplicações web, com ênfase no framework Next.js. No canto superior esquerdo, o título "Geração estática" é destacado, seguido pela afirmação "O HTML é gerado em built-time e reutilizado para cada solicitação." Ao centro, o logotipo do Next.js é apresentado como ponto de partida do processo, que segue para a direita com a ação "Cria o aplicativo para produção". Isso leva à representação de uma página web indicando "O HTML é gerado". Três figuras humanas a__linhadas horizontalmente seguem, com setas apontando para cada uma delas a partir da página web, e a frase "Reutilizado para cada solicitação" conclui o processo. Este diagrama visual demonstra que o HTML gerado durante o tempo de construção (built-time) é servido de forma estática para cada usuário que acessa a aplicação, otimizando o desempenho e a velocidade de carregamento. A imagem é projetada em azul e branco, utilizando um estilo técnico e informativo.

Esse conteúdo estático é então guardado em cache e pode ser distribuído por uma rede de entrega de conteúdo (CDN), acelerando o carregamento para os usuários.

É uma abordagem eficaz quando você tem conteúdo que não muda frequentemente ou não precisa ser personalizado para cada visitante.

Como implementar um site estático com Next.js?

Quando utilizamos o App Router, a renderização no Next.js é um processo automático e inteligente.

Durante esse processo, se o Next.js encontrar alguma função dinâmica ou pedido de dados não cacheados, ele muda para a renderização dinâmica da rota inteira.

Basicamente, o Next.js decide se uma rota será estática ou dinâmica baseando-se em como os dados e funções são utilizados. Preparei uma tabela para mostrar como isso funciona:

Funções DinâmicasDadosRota
NãoCacheadosEstaticamente renderizada
SimCacheadosDinamicamente renderizada
NãoNão cacheadosDinamicamente renderizada
SimNão cacheadosDinamicamente renderizada

Nessa tabela, para uma rota ser completamente estática, todos os dados devem estar cacheados.

Porém, você pode ter rotas dinamicamente renderizadas que usam tanto dados cacheados quanto não cacheados.

Como pessoa desenvolvedora, você não precisa escolher entre renderização estática ou dinâmica, pois o Next.js automaticamente escolhe a melhor estratégia para cada rota com base nas funcionalidades e APIs usadas.

Em vez disso, você decide quando "cacheear" ou revalidar dados específicos e pode optar por transmitir partes da sua interface de usuário.

Se quiser se aprofundar no assunto

Aqui na Alura, temos várias formações focadas no Next, vamos conhecê-las?

Nessa formação, trabalhamos com a versão 12 do Next. Inicialmente, você vai conhecer um pouco sobre o Next.js, que tipos de problema ele se propõe a resolver e quais as vantagens em utilizá-lo.

Além disso, você vai aprender conceitos chave da ferramenta e ver na prática como criar suas primeiras páginas usando o framework.

Nessa formação, trabalhamos com a versão 12 do Next. Durante os cursos você criará componentes reutilizáveis e escaláveis para o Front-End usando as melhores práticas em Next.js.

Além disso, você aplicará conteúdos estáticos usando o File System para tornar seu site mais performático e rápido.

Nessa formação, trabalhamos com a versão 13 do Next. Nela, você aprenderá o que é e como construir um Design System usando as tecnologias mais populares de desenvolvimento web.

Você mergulhará no mundo do Design Atômico e aprenderá construindo um projeto prático com Next.js e Typescript.

Conclusão

O Next.js se destaca no cenário de desenvolvimento web por sua abordagem inteligente e flexível, particularmente no que diz respeito às técnicas de renderização.

Aqui estão alguns pontos-chave que resumem as informações únicas sobre o Next.js:

  • Renderização automática e inteligente: O Next.js escolhe automaticamente entre renderização estática e dinâmica com base na natureza dos dados e funções em cada rota.

Isso elimina a necessidade das pessoas desenvolvedoras decidirem manualmente qual método de renderização usar, otimizando tanto a performance quanto a experiência do usuário.

  • Server Components por padrão: Com o App Router, o Next.js utiliza Componentes de Servidor por padrão, permitindo renderizações eficientes no servidor sem configurações extras.

Isso traz benefícios significativos em termos de performance, SEO e redução do tamanho dos pacotes enviados ao cliente.

  • Flexibilidade com Client Components: Enquanto a renderização do servidor é o padrão, o Next.js permite a inclusão de Componentes de Cliente conforme necessário.

Essa flexibilidade garante que os(as) desenvolvedores(as) possam implementar interatividades complexas e específicas quando necessário, sem sacrificar os benefícios da renderização no servidor.

  • Otimização de performance: Através de técnicas como cacheamento e streaming, o Next.js melhora o tempo de carregamento das páginas e a eficiência da entrega de conteúdo, especialmente em páginas com dados estáticos ou que requerem processamento intensivo no servidor.

  • Solução híbrida para dados dinâmicos e estáticos: O Next.js oferece uma solução híbrida única, permitindo rotas dinamicamente renderizadas que utilizam tanto dados cacheados quanto não cacheados.

Isso proporciona uma grande versatilidade para desenvolver páginas que atendem a uma variedade de necessidades e cenários de uso.

Vinicios Neves
Vinicios Neves

Vinicios Neves, Tech Lead e Educador, mistura código e didática há mais de uma década. Especialista em TypeScript, lidera equipes full-stack em Lisboa e inspira futuros desenvolvedores na FIAP e Alura. Com um pé no código e outro no ensino, ele prova que a verdadeira engenharia de software vai além das linhas de código. Além de, claro, ser senior em falar que depende.

Veja outros artigos sobre Front-end