Rotas dinâmicas em páginas estáticas no Next
Como funcionam as rotas dinâmicas? Qual a relação do getStaticPaths com o getStaticProps? Como funciona o fallback? Entenda tudo isso aqui nesta postagem!
Por Maurício Sousa | | JavascriptReactNext
No Next, se a página possuir rotas dinâmicas e usar getStaticProps, será necessário utilizar o getStaticPaths. Por que isso?
O getStaticPaths vai tentar buscar quais rotas existem para mapeá-los. Esse mapeamento vai ser utilizado pelo getStaticProps na hora da build, ou seja, vai ser feito um pre-render de todas as rotas mapeadas.
A propriedade "paths" determina quais caminhos serão pre-renderizados pelo getStaticProps.
Quando uma rota dinâmica é acessada e ela não está na lista de pre-renderizadas, existem duas opções:
Você retorna 404 direto.
// pages/posts/[id].js
function Post({ post }) {
// Render post...
}
// Esta função será chamada no momento da build
export async function getStaticPaths() {
// Requisição para obter os posts
const res = await fetch('https://.../posts');
const posts = await res.json();
// Pega os caminhos dos posts que serão pre-renderizados
const paths = posts.map((post) => ({
params: { id: post.id },
}));
// Apenas os posts presentes no array de paths serão pre-renderizados
// no momento da build.
// { fallback: false } os posts que não estão mapeados, ou seja, não
// foram pre-renderizados, retornarão 404 ao serem acessados.
return { paths, fallback: false };
}
// Esta função também será chamada na build.
export async function getStaticProps({ params }) {
// params contém o `id` do post.
// Se a rota for /posts/1, então params.id é 1
const res = await fetch(`https://.../posts/${params.id}`);
const post = await res.json();
// Passa os dados do post para página via props
return { props: { post } };
}
export default Post;
O next vai gerar estaticamente o HTML da página, isso inclui executar o getStaticProps. Na execução do StaticProps, você pode usar uma verificação para saber se algum dado foi retornado da API, e então retornar 404 ou não.
export default function Post({ posts }) {
const router = useRouter();
// Se a página não estiver pre-renderizada, ela vai cair no fall back e
// mostrar o componente de loading. Ao mesmo tempo, no background, a
// função getStaticProps estará sendo executada.
if (router.isFallback) return <h1>Carregando ...</h1>;
return (
// Render post...
);
}
export const getStaticPaths = async () => {
return {
// Todas as rotas cairão no fallback
paths: [],
fallback: true,
};
};
export const getStaticProps = async (ctx) => {
let data = null;
try {
// Requisição para pegar os posts.
data = await loadPosts({ post: ctx.params.slug });
} catch (error) {
data = null;
}
// Se não houverem posts, retornará 404.
if (!data || !data.posts || !data.posts.length) {
return {
notFound: true,
};
}
// Quando chegar aqui, a página vai sair do fallback e será renderizada
// com os dados passados via props.
return {
props: {
posts: data.posts,
},
};
};
- Este comportamento, quando o fallback é true, é muito bacana. Se não for encontrado um arquivo estático para aquela rota, esse arquivo é gerado no formato JSON e enviado ao browser do usuário. Ao mesmo tempo, essa rota é adicionada na lista de páginas pre-renderizadas, então, os acessos subsequentes na rota serão servidos com uma página gerada da mesma forma que as outras páginas, pre-renderizadas no momento da build, foram geradas.