# Como o Nuqs resolve URL State no React?

> Published 2026-10-11T13:56:29.929Z on https://www.crazystack.com.br/pt/p/como-o-nuqs-resolve-url-state-no-react/
> Source video: https://www.youtube.com/watch?v=BX6mqoazj1s

Guardar estado só no navegador é um erro silencioso: o estado desaparece no reload e nunca é compartilhável. O Nuqs ataca isso colocando o estado na URL. A ideia parece simples, mas a biblioteca resolve tipagem, listas, booleanos, paginação e debounce, além de se encaixar bem no modelo de Server Components do Next.js.

## O que é o Nuqs e por que guardar URL state

O [Nuqs](https://github.com/47ng/nuqs) é uma biblioteca open source que armazena o estado do React diretamente na URL, substituindo o useState tradicional quando você quer filtros e diálogos compartilháveis. A ideia central é simples: em vez de guardar o filtro em uma variável local do navegador, você o escreve na query string, tipado e legível por qualquer parte da aplicação. A documentação oficial fica em [nuqs.47ng.com](https://nuqs.47ng.com).

O problema que a biblioteca ataca aparece em dois cenários comuns. O primeiro é a tabela com filtro: você seleciona a categoria "headset", guarda em um state e recarrega a página. O filtro desaparece, porque o state vive só na memória do navegador. O segundo é o dialog com um state `isOpen`: você quer mandar por e-mail um link que já abre o popup de cadastro, mas um state local não viaja no link.

Com URL state, os dois casos se resolvem de graça. O usuário recarrega e volta exatamente onde estava; você copia o link com `?categoria=headset` e o colega vê a mesma tela filtrada. E uma campanha promocional pode enviar `?isDialogOpen=true`, fazendo a aplicação abrir o cadastro já na carga da página. O padrão de nomenclatura fica a seu critério, em snake case, camelCase ou o que o time preferir.

## Como o useQueryState funciona na prática

O `useQueryState` é o hook que você mais vai usar, e ele existe para substituir o useState com a menor fricção possível. Ele cria um estado ligado a um parâmetro da URL e devolve um par com valor e setter, numa sintaxe propositalmente parecida com o useState. Você desestrutura `[categoria, setCategoria]` e usa o setter com valor novo ou com função sobre o valor anterior, exatamente como faria com `setState`.

O primeiro argumento é o nome do parâmetro na URL, por exemplo `categoria`. O segundo é um parser, e aqui entra uma facilidade importante: com `parseAsStringLiteral` você passa uma lista de valores permitidos, como as categorias de um catálogo de produtos, ou até um enum do seu projeto. O resultado é um estado tipado, então um `if categoria === ...` autocompleta e o TypeScript valida em tempo de compilação.

A conversão de tipos fica por conta da biblioteca. Na URL tudo é string, mas o parser transforma os valores para você. Os casos mais úteis na rotina de quem trabalha com [React](https://react.dev) são:

- `parseAsStringLiteral`: string com valores restritos, tipada a partir de um enum ou lista de literais.
- `parseAsArrayOf` combinado com um parser de literal: lista de valores, separada por vírgula na URL.
- `parseAsBoolean`: booleano com valor padrão via `.withDefault(false)`, convertido automaticamente.
- `parseAsInteger`: número, ideal para paginação.
- `.withDefault`: valor padrão aplicado quando o parâmetro não existe na URL.

## Paginação, listas e o useQueryStates

Guardar a página atual na URL é um dos ganhos mais imediatos do Nuqs, porque resolve a perda de contexto no reload. Com `parseAsInteger`, o parâmetro `page` acompanha a navegação: o usuário avança para a página dois, recarrega e continua na página dois, em vez de ser jogado de volta ao início. É o mesmo raciocínio para múltiplos status em uma lista, que o Nuqs serializa separados por vírgula, como `?status=estoque,estoque-baixo`.

Quando você tem vários parâmetros relacionados, o `useQueryStates` evita declarar um hook por campo. Ele recebe um objeto em que cada chave tem seu próprio parser e devolve um único estado com todos os valores, além de um setter que atualiza o conjunto. Em uma tela de catálogo com categoria, status e página, isso mantém o componente enxuto e a URL coerente.

Vale separar bem as responsabilidades: o `useQueryState` cuida de um parâmetro, o `useQueryStates` cuida de vários, e os parsers cuidam da tipagem e da conversão. Nenhum dos três substitui o useState em todos os cenários. Estado de formulário em edição, rascunho de texto ou dados vindos de API continuam naturalmente em estado local ou em ferramentas próprias para isso.

## Debounce embutido para campos de busca

O debounce embutido no Nuqs é o recurso que mais chama atenção em campos de busca dinâmicos. Sem ele, cada caractere digitado dispara uma atualização da URL, e cada atualização pode significar uma chamada de API ou uma operação de filtro no frontend. Uma busca de 20 caracteres viraria 20 execuções do filtro, um custo fácil de evitar.

Com debounce, você configura um intervalo, por exemplo 500 milissegundos. O usuário digita, o hook espera; se ele digitar mais, o hook espera de novo, reiniciando a janela. Só quando ele para de digitar o parâmetro é escrito na URL. O efeito é visível na barra de endereço: você digita um texto longo e a query string só muda depois da pausa.

Esse comportamento combina bem com o Next.js, porque o valor do parâmetro pode ser lido pelo Server Component e usado para buscar dados. Um parâmetro `q` de busca tipado como string, atualizado com debounce, entrega uma experiência de busca contínua sem disparar requisições a cada tecla.

## Integração com Server Components no Next.js

No [Next.js](https://nextjs.org), framework React para produção, o Nuqs abre um padrão que Felipe Rocha, do canal Full Stack Club no YouTube, usa como padrão em seus projetos: o filtro vive em um Client Component, e o Server Component lê a URL para buscar os dados já filtrados no banco. A URL vira o ponto de sincronia entre as duas camadas.

A chave desse padrão é a opção `shallow`. Por padrão, ela é `true`: atualizar a URL não recarrega a página, apenas atualiza o JavaScript no cliente. Quando você define `shallow: false`, a atualização do parâmetro aciona novamente a renderização da página no servidor, o Server Component roda de novo, chama o banco e devolve os dados filtrados para o Client Component que renderiza a tabela.

O fluxo completo fica assim:

1. O Client Component com a tabela recebe os produtos e renderiza os filtros com Nuqs.
2. O usuário muda um filtro; o hook escreve o parâmetro na URL com `shallow: false`.
3. O Next.js reprocessa a página, o Server Component lê `searchParams` e consulta o banco aplicando o filtro.
4. Os dados atualizados descem para a tabela, e a URL já documenta o estado da tela.

O Nuqs não é exclusivo do Next.js. Em um projeto com [Vite](https://vite.dev) ou outro bundler, os hooks funcionam do mesmo modo; a integração com Server Components é que intensifica o ganho, porque a URL passa a alimentar a renderização no servidor. Vale lembrar que usar `shallow: false` em toda atualização tem um custo: cada mudança de filtro gera uma viagem ao servidor, o que costuma ser aceitável justamente quando o dado precisa vir do banco.

A abordagem também ganhou tração fora dos tutoriais: em dezembro de 2025, o [InfoQ cobriu uma palestra sobre gerenciamento de URL state tipado com Nuqs no React Advanced 2025](https://www.infoq.com/news/2025%2F12), e tutoriais como o [publicado no dev.to em 8 de dezembro de 2025](https://dev.to/tphilus) mostram o mesmo caminho de converter lógica de query params em hooks tipados.

## Por que a tipagem na URL importa para o seu projeto?

A tipagem na URL importa porque elimina uma classe inteira de bugs de conversão e digitação. Sem um parser, todo parâmetro chega como string solta, e cabe a você lembrar de converter para número, validar booleanos e conferir valores inválidos em cada componente que lê a query string.

Com os parsers do Nuqs, o contrato do parâmetro fica declarado em um lugar só. O `parseAsInteger` garante que `page` é número, o `parseAsBoolean` converte a string da URL para verdadeiro ou falso, e o `parseAsStringLiteral` restringe os valores aceitos. O resultado é que a URL deixa de ser uma fonte de strings improváveis e passa a se comportar como um estado tipado, validado pelo TypeScript antes do deploy.

## Onde o Nuqs encaixa na sua stack hoje?

O Nuqs encaixa em qualquer projeto React que tenha filtros, abas, paginação ou diálogos que precisam sobreviver ao reload. Em 2025, a biblioteca consolidou-se como referência de URL state no ecossistema React, com a documentação oficial descrevendo a proposta como "useState, mas armazenado na query string" ([nuqs.dev](https://nuqs.dev)).

Na prática, o caminho mais comum é começar com um único parâmetro, como o filtro de categoria de uma tabela, e evoluir para o `useQueryStates` quando a tela acumula parâmetros relacionados. Se você usa Next.js com Server Components, o passo seguinte é ligar os filtros ao servidor com `shallow: false` e deixar a URL alimentar a consulta ao banco.

## Perguntas frequentes sobre Nuqs

- **O Nuqs substitui o useState em todos os casos?**

Não. Ele substitui o useState quando o estado precisa sobreviver ao reload, ser compartilhável por link ou alimentar o servidor. Estado de formulário em edição, rascunhos e dados derivados de API seguem melhor em estado local ou em ferramentas dedicadas.

- **O Nuqs funciona fora do Next.js?**

Sim. A biblioteca funciona em qualquer aplicação React, incluindo projetos com Vite. O que muda no Next.js é a integração com Server Components, em que a URL pode disparar nova renderização no servidor via `shallow: false`.

- **Como o Nuqs armazena listas na URL?**

Com `parseAsArrayOf` e um parser interno, como `parseAsStringLiteral`. Os valores são serializados separados por vírgula, por exemplo `?status=estoque,estoque-baixo`, e voltam como array tipado no seu componente.

- **O debounce do Nuqs serve só para busca?**

O caso de uso clássico é o campo de busca, em que você não quer uma requisição por caractere. Qualquer parâmetro atualizado com frequência pelo usuário se beneficia, porque o debounce adia a escrita na URL até que a digitação pare.

- **Usar shallow: false tem desvantagem?**

Cada atualização do parâmetro aciona o servidor novamente, o que aumenta o tráfego e a latência percebida. Em telas em que o filtro deve refinar dados vindos do banco, o custo é compensado; em mudanças puramente visuais, o padrão `shallow: true` é suficiente.

- **Quanto pesa a biblioteca Nuqs no bundle?**

Felipe Rocha destaca no vídeo que a biblioteca é muito leve para instalar, e a proposta dela é justamente substituir código de manipulação de query string que você escreveria à mão. Como os hooks só entram nos componentes que usam URL state, o impacto no bundle fica limitado a essas telas.

- **Qual a diferença entre useQueryState e useQueryStates?**

O `useQueryState` controla um parâmetro por hook, com valor e setter dedicados. O `useQueryStates` recebe um objeto com vários parâmetros e parsers, e devolve um único estado com todos os valores mais um setter que atualiza o conjunto de uma vez.

- **Como ler os parâmetros do Nuqs em um Server Component?**

No Next.js, a página recebe `searchParams` como props, e você tipa cada parâmetro esperado, por exemplo `q` como string. Com `shallow: false`, cada atualização do filtro no cliente reprocessa a página e entrega os valores atualizados para o servidor consultar o banco.

- **Vale aprender Nuqs em 2025?**

Sim, especialmente se você trabalha com Next.js e Server Components. A cobertura do React Advanced 2025 no InfoQ mostra o tema circulando em eventos da comunidade, e o padrão de URL state tipado resolve dores reais de filtros, paginação e compartilhamento de links.

## Do vídeo ao artigo: leve esse conteúdo adiante

O que tornou esse conteúdo útil foi a progressão clara do problema ao código: primeiro a dor do useState perdido no reload, depois cada hook do Nuqs resolvendo uma fatia dela. Se você também tem explicações assim gravadas em vídeos, aulas, mentorias ou lives, esse conhecimento merece uma versão escrita que a busca encontra.

O [Skala Blog](https://skalablog.com) faz exatamente essa ponte: você cola a URL de um vídeo do YouTube, a transcrição é gerada e o artigo estruturado sai pronto para você revisar e publicar. Vale para tutoriais como este do Nuqs, para o material do [Gustavo Dev Doido](https://crazystack.com.br) no [Bootcamp do Dev Doido](https://crazystack.com.br) e para quem produz conteúdo sobre o [Crazystack Typescript](https://crazystack.com.br).

Se o seu canal guarda horas de conhecimento técnico, teste o fluxo no [Skala Blog](https://skalablog.com): vídeo, transcrição, artigo. O estado do seu conteúdo, como no Nuqs, fica registrado em um formato que outras pessoas conseguem acessar e compartilhar.

[Source video](https://www.youtube.com/watch?v=BX6mqoazj1s)
