# Como Implementar Validação de CPF com React Server Components no Next.js

> Aprenda a implementar validação de CPF usando React Server Components no Next.js com integração à API do CPFHub.io.

**Publicado:** 12/12/2024
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/validacao-cpf-react-server-components-nextjs

---


React Server Components no Next.js permitem buscar dados diretamente no servidor sem expor lógica sensível ao cliente — o que os torna ideais para validação de CPF via API: a chave de API fica protegida, a resposta é mais rápida e o bundle do cliente fica menor. Esta abordagem combina Server Components para o fetch com Client Components para interatividade e Server Actions para a submissão de formulários, resultando em uma arquitetura moderna e segura integrada à API da CPFHub.io.

## Introdução

O Next.js revolucionou a forma como construímos aplicações React, e os **React Server Components** (RSC) trouxeram um novo paradigma para buscar dados no servidor sem expor lógica sensível ao cliente. Quando se trata de validação de CPF, essa abordagem é ideal: a chave de API permanece no servidor, a resposta é mais rápida e o bundle do cliente fica menor.

---

## Por que usar React Server Components para validação de CPF

Os Server Components executam exclusivamente no servidor, o que traz vantagens significativas para operações que envolvem dados sensíveis como CPFs.

| Característica | Client Component | Server Component |
|---------------|-----------------|-----------------|
| Execução | Navegador | Servidor |
| Acesso a API keys | Exposta no bundle | Protegida no servidor |
| Bundle size | Aumenta com libs | Zero impacto |
| Fetch de dados | useEffect + estado | Direto no render |
| SEO | Requer SSR adicional | Nativo |

- **Segurança** -- a chave de API nunca chega ao navegador, eliminando riscos de vazamento
- **Performance** -- o fetch acontece no servidor, mais próximo da API, reduzindo latência
- **Simplicidade** -- sem necessidade de useEffect, useState ou gerenciamento de loading states no servidor
- **LGPD** -- dados sensíveis do CPF podem ser filtrados antes de chegar ao cliente

---

## Criando o Server Component de consulta

No Next.js 14+, todo componente dentro da pasta `app/` é um Server Component por padrão. Crie o arquivo `app/cpf/[cpf]/page.tsx` para uma rota dinâmica.

```tsx
// app/lib/cpf-api.ts
interface CPFResponse {
 success: boolean;
 data: {
 cpf: string;
 name: string;
 nameUpper: string;
 gender: string;
 birthDate: string;
 day: string;
 month: string;
 year: string;
 };
}

export async function consultarCPF(cpf: string): Promise<CPFResponse> {
 const response = await fetch(`https://api.cpfhub.io/cpf/${cpf}`, {
 headers: {
 "x-api-key": process.env.CPFHUB_API_KEY!,
 },
 next: { revalidate: 3600 },
 });

 if (!response.ok) {
 throw new Error(`Erro na consulta: ${response.status}`);
 }

 return response.json();
}
```

```tsx
// app/cpf/[cpf]/page.tsx
import { consultarCPF } from "@/app/lib/cpf-api";
import { notFound } from "next/navigation";

interface Props {
 params: { cpf: string };
}

export default async function CPFPage({ params }: Props) {
 try {
 const resultado = await consultarCPF(params.cpf);

 if (!resultado.success) {
 notFound();
 }

 return (
 <div className="max-w-md mx-auto p-6">
 <h1 className="text-2xl font-bold mb-4">Resultado da Consulta</h1>
 <dl className="space-y-2">
 <dt className="font-semibold">Nome</dt>
 <dd>{resultado.data.name}</dd>
 <dt className="font-semibold">CPF</dt>
 <dd>{resultado.data.cpf}</dd>
 <dt className="font-semibold">Data de Nascimento</dt>
 <dd>{resultado.data.birthDate}</dd>
 </dl>
 </div>
 );
 } catch {
 notFound();
 }
}
```

- **process.env.CPFHUB_API_KEY** -- variável de ambiente acessível apenas no servidor, nunca exposta ao cliente
- **next: { revalidate: 3600 }** -- cache de uma hora para evitar chamadas desnecessárias à API
- **notFound()** -- função do Next.js que retorna um 404 elegante quando o CPF não é encontrado

---

## Adicionando o Client Component para o formulário

O formulário de entrada precisa de interatividade, portanto deve ser um Client Component. Use a diretiva `"use client"` e navegue programaticamente para a rota do Server Component.

```tsx
// app/components/CPFForm.tsx
"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";

function formatarCPF(valor: string): string {
 const numeros = valor.replace(/\D/g, "").slice(0, 11);
 return numeros
 .replace(/(\d{3})(\d)/, "$1.$2")
 .replace(/(\d{3})(\d)/, "$1.$2")
 .replace(/(\d{3})(\d{1,2})$/, "$1-$2");
}

export default function CPFForm() {
 const [cpf, setCpf] = useState("");
 const [erro, setErro] = useState("");
 const router = useRouter();

 function handleSubmit(e: React.FormEvent) {
 e.preventDefault();
 const numeros = cpf.replace(/\D/g, "");
 if (numeros.length !== 11) {
 setErro("CPF deve conter 11 dígitos");
 return;
 }
 setErro("");
 router.push(`/cpf/${numeros}`);
 }

 return (
 <form onSubmit={handleSubmit} className="space-y-4">
 <input
 type="text"
 value={cpf}
 onChange={(e) => setCpf(formatarCPF(e.target.value))}
 placeholder="000.000.000-00"
 className="border p-2 rounded w-full"
 />
 {erro && <p className="text-red-500">{erro}</p>}
 <button type="submit" className="bg-blue-600 text-white px-4 py-2 rounded">
 Consultar CPF
 </button>
 </form>
 );
}
```

- **"use client"** -- diretiva obrigatória para componentes que usam hooks como useState e useRouter
- **formatarCPF** -- máscara aplicada em tempo real enquanto o usuário digita
- **router.push** -- navegação para a rota do Server Component que fará o fetch seguro

---

## Implementando Server Actions para validação inline

A partir do Next.js 14, **Server Actions** permitem executar código no servidor diretamente a partir de formulários, sem criar rotas de API separadas.

```tsx
// app/actions/validar-cpf.ts
"use server";

import { consultarCPF } from "@/app/lib/cpf-api";

export async function validarCPFAction(formData: FormData) {
 const cpf = formData.get("cpf") as string;
 const numeros = cpf.replace(/\D/g, "");

 if (numeros.length !== 11) {
 return { erro: "CPF deve conter 11 dígitos", dados: null };
 }

 try {
 const resultado = await consultarCPF(numeros);
 if (!resultado.success) {
 return { erro: "CPF não encontrado", dados: null };
 }
 return {
 erro: null,
 dados: {
 nome: resultado.data.name,
 nascimento: resultado.data.birthDate,
 },
 };
 } catch {
 return { erro: "Erro ao consultar a API. Tente novamente.", dados: null };
 }
}
```

```tsx
// app/components/CPFFormAction.tsx
"use client";

import { useActionState } from "react";
import { validarCPFAction } from "@/app/actions/validar-cpf";

export default function CPFFormAction() {
 const [state, formAction, pending] = useActionState(validarCPFAction, {
 erro: null,
 dados: null,
 });

 return (
 <form action={formAction} className="space-y-4">
 <input name="cpf" placeholder="000.000.000-00" className="border p-2 rounded w-full" />
 <button type="submit" disabled={pending} className="bg-blue-600 text-white px-4 py-2 rounded">
 {pending ? "Consultando..." : "Validar CPF"}
 </button>
 {state.erro && <p className="text-red-500">{state.erro}</p>}
 {state.dados && <p className="text-green-600">Nome: {state.dados.nome}</p>}
 </form>
 );
}
```

- **"use server"** -- marca a função como Server Action, executada exclusivamente no servidor
- **useActionState** -- hook que gerencia estado do formulário com Server Actions
- **pending** -- estado de loading automático enquanto a action executa no servidor

---

## Perguntas frequentes

### Qual a diferença entre usar um Server Component e uma Server Action para consultar CPF?
Um Server Component faz o fetch no momento da renderização da página — útil para rotas como `/cpf/[cpf]` onde o CPF já está na URL. Uma Server Action é acionada pela submissão de um formulário — útil para consultas inline sem mudar de página. As duas abordagens mantêm a API key no servidor; a escolha depende do fluxo de UX desejado.

### Como o Next.js garante que a chave de API nunca vaze para o cliente?
Variáveis de ambiente sem o prefixo `NEXT_PUBLIC_` nunca são incluídas no bundle do cliente. Server Components e Server Actions executam exclusivamente no Node.js do servidor — o navegador recebe apenas o HTML renderizado ou a resposta serializada da action, sem nenhum código ou dado de servidor. Consulte a [documentação de variáveis de ambiente do Next.js](https://nextjs.org/docs/app/building-your-application/configuring/environment-variables) para detalhes.

### A API da CPFHub.io retorna HTTP 429 se o limite de consultas for atingido?
Não. A CPFHub.io não retorna HTTP 429 nem bloqueia requisições ao atingir a cota. Consultas excedentes ao plano gratuito (50/mês) são cobradas automaticamente a R$0,15 cada. Acompanhe o consumo em [app.cpfhub.io/settings/billing](https://app.cpfhub.io/settings/billing) e configure alertas antes de atingir o limite, se necessário.

### Como adicionar cache às consultas de CPF em Server Components?
Use a opção `next: { revalidate: N }` no `fetch` — onde N é o tempo em segundos. Para CPFs que raramente mudam, `revalidate: 3600` (1 hora) evita chamadas repetidas à API. Você também pode usar `cache: 'force-cache'` para cache permanente até um `revalidatePath` ou `revalidateTag` explícito — útil em sistemas de onboarding onde o mesmo CPF é consultado várias vezes no fluxo.

### Leia também

- [Diferença entre validação de CPF e consulta de CPF: quando usar cada uma](https://cpfhub.io/blog/diferenca-entre-validacao-de-cpf-e-consulta-de-cpf-quando-usar-cada-uma)
- [API de CPF grátis para desenvolvedores: como começar em 5 minutos](https://cpfhub.io/blog/api-cpf-gratis-desenvolvedores-comecar-5-minutos)
- [Onboarding digital em fintechs: como validar CPF em menos de 30 segundos](https://cpfhub.io/blog/onboarding-digital-em-fintechs-como-validar-cpf-em-menos-de-30-segundos)
- [KYC no Brasil: quais setores são obrigados a validar CPF por lei](https://cpfhub.io/blog/kyc-no-brasil-quais-setores-sao-obrigados-a-validar-cpf-por-lei)

---

## Conclusão

React Server Components no Next.js oferecem a combinação ideal de segurança e performance para validação de CPF. A chave de API permanece protegida no servidor, o bundle do cliente fica leve e a experiência do usuário é fluida. Combinando Server Components para fetch de dados com Client Components para interatividade e Server Actions para submissão de formulários, você obtém uma arquitetura moderna e robusta.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) — 50 consultas mensais gratuitas, sem cartão de crédito — e integre a validação de CPF aos seus Server Components e Server Actions em menos de 30 minutos.

