7 erros comuns no Next.js e como resolvê-los

7 erros comuns no Next.js e como resolvê-los
AdsTerra, Junte-se ao AdsTerra

O Next.js é atualmente um dos frameworks web de crescimento mais rápido em termos de adoção. Além de recursos como geração de site estático, renderização no lado do servidor e roteamento de arquivos, a equipe do Next.js continua adicionando novos recursos para tornar a construção de aplicativos web altamente otimizados e performáticos super fácil.

Apesar dos muitos benefícios e recursos que o Next.js oferece aos desenvolvedores, assim como acontece com qualquer framework, você pode encontrar erros em seu código durante o desenvolvimento. O Next faz um bom trabalho ao registrar mensagens úteis, mas ainda assim você pode encontrar alguns erros difíceis de depurar.

Hydration errors(erros de hidratação) no Next.js

Um erro comum que você provavelmente encontrará tanto em aplicativos Next quanto em aplicativos React é o erro de hidratação. Erros de hidratação resultam de uma inconsistência entre a marcação renderizada no servidor e no cliente, bem como diferenças nos estados dos componentes.

Especificamente, os erros de hidratação do Next.js surgem quando você envolve seus componentes ou elementos HTML com uma tag inadequada. Um exemplo comum é quando você tem uma tag p envolvendo divs, seções ou outros elementos.

A mensagem de erro exata que você receberá é:

Hydration failed because the initial UI does not match what was rendered on the server

Para corrigir o erro, você precisa verificar a marcação em todo o seu aplicativo e garantir que você não está envolvendo elementos ou componentes personalizados com tags inadequadas.

Por exemplo, o seguinte componente resultará em um erro de hidratação do Next.js porque envolvemos o elemento div dentro do parágrafo:

import Image from 'next/image'

export const ComponenteErro = () => {
  return (
    <p>
      <div>Não faça isso!</div>
      <Image src='/logo.jpg' alt='' width='40' height='40'/>
    </p>
  )
}

Em vez disso, use os elementos de "embrulho" corretos, como div, section, main, etc., para envolver seu conteúdo:

export const ComponenteCorreto = () => {
  return (
    <div>
      <div>Faça isso!</div>
      <Image src='/logo.jpg' alt='' width='40' height='40'/>
    </div>
  )
}

Lembre-se de que alguns componentes de terceiros, como os do MUI, podem usar a tag <p> como elemento de nível superior. Em tais casos, você precisará envolver o componente em algo semântico para evitar o erro, como um <div> ou <section>.

Organizar corretamente seu HTML reduzirá significativamente a probabilidade de encontrar o erro de hidratação em seu aplicativo Next, mas não é a única causa. Você também pode encontrar o erro após importar e executar determinados pacotes, como exploraremos na próxima seção.

Erro no objeto Documento ou Window

Quando você tenta acessar o objeto window enquanto o componente ainda está sendo montado, o Next.js lançará um erro informando que o documento ou window não está definido. Esse erro também ocorre quando você instala e usa uma biblioteca que tenta acessar o objeto window antes que o componente seja montado.

Suponha que você tenha um arquivo home.js em seu aplicativo Next.js. Tentar acessar o armazenamento local resultará no erro window is not defined:

const Home = () => {
  const saveSession = (event) => {
    window.sessionStorage.setItem("key", event.target.value)
  }   

  return (
      <div>
        <input
          type="text"
          id="message"
          name="message"
          onChange={saveSession}
          value={message}
        />
      </div>
  );
};

export default Home;

Isso é válido também para bibliotecas de terceiros. Por exemplo, digamos que você tenha instalado o pacote swiperjs e a biblioteca tente acessar o objeto window internamente. Usar o swiperjs conforme demonstrado no código abaixo também resultará no mesmo erro:

import { Swiper } from 'swiperjs'

const Home = () => {
  return (
    <>
      <Swiper
        spaceBetween={50}
        slidesPerView={3}
        navigation
        pagination={{ clickable: true }}  
       >
        // Slides aqui
      </Swiper>
    </>
  );
};

export default Home;

Esse erro ocorre porque o Swiper é renderizado antes de poder acessar o objeto window. Para resolver esse erro, você precisa executar o código que acessa o objeto window do navegador dentro do Hook useEffect(). Dessa forma, o código só é executado após o componente ter sido montado.

Aqui está como você reescreveria o primeiro exemplo para que funcione:

const Home = () => {
  const saveSession = (event) => {
    useEffect(() => {
      window.sessionStorage.setItem("key", event.target.value)
    })
  }    

  return (
      <div>
        <input
          type="text"
          id="message"
          name="message"
          onChange={saveSession}
          value={message}
        />
      </div>
  );
};

export default Home;

Se você estiver usando uma biblioteca que acessa o objeto window, você precisa carregar a biblioteca somente após o componente ter sido montado. Por exemplo, é assim que você carregaria o Swiper para evitar o erro:

const Home = () => {
  const [domLoaded, setDomLoaded] = useState(false);

  useEffect(() => {
    setDomLoaded(true);
  }, []);

  return (
    <>
      {domLoaded && (
        <Swiper
          spaceBetween={50}
          // ...
        >
          <div>Teste</div>
        </Swiper>
      )}
    </>
  );
};

export default Home;

Falha na construção devido a erros do webpack

Após executar o comando de construção (build) do Next.js para criar o seu aplicativo, você pode receber uma mensagem de erro informando que a construção falhou devido a erros do webpack:

Cannot read property 'asString' of undefined

> Build error occurred
Error: > Build failed because of webpack errors

O Next.js v11 e versões mais recentes usam o webpack 5 por padrão. No entanto, esse erro ocorre apenas com o webpack 4.

Para resolver o problema, você precisa habilitar o webpack 5 no seu aplicativo Next.js. Você pode fazer isso adicionando a seguinte configuração no arquivo next.config.js:

module.exports = {
  // Adicione isso:
  future: {
    webpack5: true,
  },
};

Erros relacionados a APIs e slugs

Uma grande quantidade de erros no Next.js está relacionada a APIs e slugs. O Next.js fornece duas APIs para busca de dados — getStaticPaths e getServerSideProps. No entanto, essas funções podem gerar um erro se não forem usadas corretamente.

Aqui está um erro que você pode encontrar com frequência ao usar a API getStaticProps:

Error: getStaticPaths is required for dynamic SSG pages and is missing for '/productsPage/[slug]'

Você recebe esse erro quando renderiza uma página no lado do servidor com a funcionalidade SSG, mas não define a função getStaticProps no componente da página.

Isso ocorre porque o Next.js exige a função getStaticPaths para construir páginas renderizadas no lado do servidor ou geradas estaticamente que usam rotas dinâmicas. Portanto, a solução é simplesmente adicionar uma função getStaticPaths() ao componente da página para /nomePagina/[slug].

Vamos ver um exemplo. Em uma loja de comércio eletrônico hipotética, a página /nomePagina/[slug] poderia mostrar os detalhes de um produto específico.

Nesse caso, você pode usar a função getStaticPaths para recuperar uma lista de todos os slugs de produtos disponíveis de um banco de dados e, em seguida, retornar a lista para ser usada como parâmetro [slug]:

export async function getStaticPaths() {
  const res = await fetch('http://localhost/caminho/para/produtos')
  const produtos = await res.json()
  const slugs = produtos.map(produto => produto.slug)

  return {
    paths: slugs.map((slug) => ({ params: { slug } })),
    fallback: false
  }
}

Erro ao importar módulos

Ao importar módulos para o seu aplicativo Next.js, você pode se deparar com o erro Module not found:

Module not found: Can't resolve 'fs'

Isso significa que o Next.js não consegue localizar o módulo especificado na mensagem de erro. Se você está usando um módulo local, precisa especificar o caminho correto. Mas se é um módulo npm ou Yarn, o erro geralmente ocorre porque o módulo não está disponível no lado do cliente.

Uma maneira de corrigir esse problema é garantir que todo o código relacionado ao Node.js e ao servidor esteja dentro das APIs de busca de dados do Next.js — getServerSideProps, getStaticPaths ou getStaticProps:

export function Home({ fileInfo }) {
  return (
    <div>
      {/* conteúdo da página */}
    </div>
  );
}

export default Home;

export async function getServerSideProps(context) {
  const util = require('util');
  const tring = util.format(1, 2, 3);

  return {
    props: {
      fileInfo,
    },
  };
}

Se isso não resolver o problema, verifique se as letras maiúsculas e minúsculas do nome do arquivo que você está tentando importar estão corretas. Aqui está um exemplo:

// components/MeuComponente.js
export default function MeuComponente() {
  return <h1>Olá</h1>
}

Ao importar o componente acima, você precisa usar o mesmo formato de letras do nome do arquivo:

// pages/index.js

// Isso não funcionará
import MeuComponente from '../components/Meucomponente'

// Isso funcionará
import MeuComponente from '../components/MeuComponente'

Observe que o uso incorreto de letras maiúsculas e minúsculas resultará apenas em erros de Módulo não encontrado em ambientes sensíveis a maiúsculas e minúsculas.

Erro de CORS — Depurando rotas de API do Next.js

O diretório /pages/api é onde você coloca todos os arquivos responsáveis pelo tratamento das solicitações de API, com o nome do arquivo correspondendo ao endpoint. O Next.js então mapeia automaticamente esses arquivos para a URL /api/*, que você pode acessar dentro do aplicativo por meio de solicitações de API assíncronas.

Depois de implantar seu aplicativo na internet, o aplicativo existirá em uma origem diferente. Como resultado, tentar acessar o endpoint da API resultará em um erro de CORS, como mostrado abaixo:

Access to fetch at 'http://example.com/api/test' from origin 'http://localhost:3000' has been blocked by CORS policy

Para corrigir o problema de CORS, você precisa usar o CORS para lidar com solicitações de origem cruzada. Comece instalando o pacote CORS:

npm install cors
# OR
yarn add cors

Após a conclusão da instalação, você pode importar a biblioteca e usá-la para executar um middleware personalizado logo antes da resposta da API ser recebida. Aqui está um exemplo em que configuramos os métodos POST, GET e HEAD para este endpoint:

// pages/api/test.js

import Cors from "cors";

const cors = Cors({
  methods: ["POST", "GET", "HEAD"],
});

function middleware(req, res, fn) {
  return new Promise((resolve, reject) => {
    fn(req, res, (result) => {
      if (result instanceof Error) {
        return reject(result);
      }
      return resolve(result);
    });
  });
}

export default async function runMiddleware(req, res) {
  await middleware(req, res, cors);

  // Outra lógica da API
  res.json({ resultado: resultado });
}

Com este código, podemos fazer todos os quatro tipos de solicitações de API para uma origem diferente com sucesso, sem encontrar o erro de CORS.

Capturando todos os erros em seu aplicativo Next.js

Ao criar seu aplicativo Next.js, é importante capturar todos os erros e garantir que cada um deles seja tratado. A melhor maneira de fazer isso é no nível do componente, usando a sintaxe try...catch.

No exemplo a seguir, se algum erro for encontrado ao buscar dados da API, registramos o erro, renderizamos a página de erro integrada e passamos um código de status 503:

import fetch from "isomorphic-fetch"
import Error from "next-error"

class Home extends React.Component {
  static async getInitialProps() {
    let products = [];

    try {
       const resp = fetch("https://my-store.com")
       products = await resp.json()
    } catch(err) {
       console.log(err)
    }

    return { products }
  }

  render () {
    const { products } = this.props

    if(products.length === 0) {
      return <Error statusCode={503} />
    }

    return (
     <div>
       {products.map((product) => (
         <h3 key={product.id}>{product.title}</h3> 
       ))}
     </div>
    )
  }
}

Conclusão

O Next.js está crescendo em popularidade e uso. Mas, assim como qualquer outra tecnologia, um aplicativo construído com o Next.js não está imune a erros e problemas.

Ao ler sobre erros comuns no Next.js, as causas desses erros e suas respectivas soluções — como abordamos neste artigo —, você pode otimizar seu aplicativo da web e garantir que ele funcione conforme o esperado.

Sugestões de cursos

Descubra o caminho para se tornar um especialista em programação web. Aprenda HTML, CSS, JavaScript e os principais frameworks nesta jornada emocionante. Com instrutores experientes e materiais práticos, você desenvolverá habilidades práticas para criar sites impressionantes e aplicativos interativos. Impulsione sua carreira na indústria de tecnologia e abra portas para oportunidades de emprego lucrativas. Garanta sua vaga hoje mesmo e inicie sua jornada para se tornar um desenvolvedor web de sucesso.

Método Para Aprender a Programar do Absoluto ZERO com Node.js, React e React Native.

Curso de Node.js, React e React Native

As tecnologias ensinadas no curso são responsáveis por muitas vagas no mercado de trabalho.

Além da alta demanda, os salários vão de R$47.000,00 até R$197.000,00 anuais tendo empresas que possibilitam o trabalho remoto e até vagas Internacionais.

Para que você possa estar apto a preencher uma dessas vagas eu vou te apresentar o passo a passo para você se tornar um verdadeiro expert nessas tecnologias.

O curso te dará o passo a passo de como criar estruturar de um sistema do zero com Node.js, React e React Native.

Saiba mais sobre o curso de Node.js, React e React Native.

AdsTerra, Junte-se ao AdsTerra