# Guia de desenvolvimento Next utilizando App Router

Por
Pedro Amorim de Gregori
Em 
Publicado 2024-02-20

# Introdução

O App Router foi introduzido na versão 13 do next.js e foi construído utilizando o React Server Components (RSCs).

O App Router trabalha com o diretório app para a criação de rotas que podem ou não ser de acesso público. Por padrão, componentes deste diretório são RSCs.

# Roteamento

# Definindo rotas

O next utiliza um sistema de roteamento baseado no sistema de arquivos. Desse modo, os diretórios são utilizados para criar as rotas que levarão a outros diretórios ou arquivos filhos e os arquivos são utilizados para definir a página da rota correspondente.

  • pai
    • exemplo
      • page.tsx

URL será: site.com/pai/exemplo

# Rotas dinâmicas

As rotas dinâmicas são utilizadas quando é necessário a utilização de segmentos de dados que variam, mas são importantes para a implementação da página. Elas podem ser "declaradas" utilizando os [] e utilizadas no código ao serem passadas como parâmetros da função da página, layout, etc.

  • [slug]
    • exemplo
      • page.tsx
page.tsx
export default function page({ params }: { params: { slug: string } }) {
	return <h1> Olá, {params.slug}! </h1>;
}

URL poderá ser: site.com/pedro/exemplo resultando em uma página com um <h1> Olá, pedro!.

# Grupo de rotas

É possível criar um diretório para agrupar certas rotas sem que o nome agregue na URL, só é necessário utilizar o () no nome do diretório.

  • (pai)
    • exemplo
      • page.tsx

URL será: site.com/exemplo

# Convenção de arquivos

Os arquivos apresentam uma certa nomenclatura a ser usada para a criação da UI. Sendo as principais:

  • Page: Esse arquivo define a UI da rota e a deixa o acesso público.
  • Layout: Define uma estrutura padrão para as páginas pertencentes a rota. Por exemplo, configurações de metadados e componentes que são utilizados em múltiplas páginas dessa rota.
  • Loading: Define a UI da rota, enquanto a página principal não estiver completa. Dependendo do design pode ser utilizada uma página esqueleto, uma barra de loading ou o que vier de sua imaginação, desde que a página de loading não fique muito pesada, desse modo, causando problemas de performance.

# Criando páginas e layouts

As páginas são arquivos com o nome page.tsx que apresentam a estrutura do React e vão desempenhar o papel de criar UIs especificas a determinada rota. Elas tornam a rota acessível para visitantes e por padrão são Server Components.

page.tsx
export default function Page() {
	return <h1>Página de exemplo.</h1>;
}

Os layouts são arquivos com o nome layout.tsx que apresentam estrutura do React e vão agregar nas UIs de múltiplas rotas. Elas não criam rotas públicas e acumulam seguindo a hierarquia de rotas. Componentes de layout devem receber o react prop children que será a página do arquivo page.tsx da rota.

layout.tsx
export default function Layout({
  children
}: {
  children: React.ReactNode
}) {
  return {
    <div>Eu sou uma navbar diferenciada, confia!</div>

    { children }

    <div>E eu sou um footer bem interessante.</div>
    }
}

# Hierarquia dos componentes

O next renderiza os arquivos especiais, vistos anteriormente, seguindo uma ordem especifica. Sendo essa, para os arquivos principais:

Layout -> Loading -> Page

Se a rota for aninhada, a hierarquia ocorrerá juntando componentes da rota pai com as do filho, como o exemplo a seguir:

  • pai
    • exemplo
      • page.tsx

A hierarquia será: Layout (Pai) -> Loading (Pai) -> Layout (Exemplo) -> Loading (Exemplo)-> Page

# Navegação entre rotas

Por motivos de performance, ao utilizar o next sempre utilize o componente built-in do next <Link> ao invés do <a> quando quiser criar navegação entre rotas no "HTML".

page.tsx
import Link from "next/link";

export default function page() {
	return (
		<div>
			<Link href="/profile">Perfil</Link>
			<Link href="/">Página inicial</Link>
		</div>
	);
}

Dependendo do contexto, nem sempre é possível utilizar um componente para realizar essa navegação. Desse modo, a utilização do hook useRouter para client components ou da função redirect para server components pode solucionar esse problema.

page.tsx
"use client";
import { useRouter } from "next/navigation";

export default function page() {
	const router = useRouter();

	return (
		<button type="button" onClick={() => router.push("/")}>
			Home
		</button>
	);
}
page.tsx
import { redirect } from "next/navigation";

export default function page() {
	return (
		<button type="button" onClick={() => redirect("/")}>
			Home
		</button>
	);
}