Para validar CPF em aplicações Svelte e SvelteKit, crie uma server route em src/routes/api/cpf/[cpf]/+server.ts que chama a API do CPFHub.io com o header x-api-key — mantendo a chave segura no servidor via $env/static/private — e consuma esse endpoint no componente Svelte com validação local dos dígitos antes da requisição. O resultado é um fluxo de validação completo, com progressive enhancement via form actions e feedback visual em tempo real.
Introdução
O Svelte e o SvelteKit vêm ganhando adoção significativa entre desenvolvedores web, oferecendo uma abordagem compilada que resulta em aplicações mais leves e rápidas que frameworks tradicionais. Para projetos brasileiros que utilizam Svelte, a validação de CPF é uma funcionalidade recorrente -- seja em formulários de cadastro, checkout de e-commerce ou sistemas internos de gestão.
Pré-requisitos
-
Node.js 18+ -- Necessário para rodar o SvelteKit.
-
Projeto SvelteKit -- Se ainda não tem, crie um com
npm create svelte@latest. -
Conta no CPFHub.io -- Crie uma conta gratuita em cpfhub.io
Configuração do ambiente
Crie um arquivo .env na raiz do projeto:
CPFHUB_API_KEY=SUA_CHAVE_DE_API
Entendendo a API
Para referência, a chamada à API do CPFHub.io:
curl -X GET https://api.cpfhub.io/cpf/12345678900 \
-H "x-api-key: SUA_CHAVE_DE_API" \
-H "Accept: application/json"
Resposta:
{
"success": true,
"data": {
"cpf": "12345678900",
"name": "João da Silva",
"nameUpper": "JOAO DA SILVA",
"gender": "M",
"birthDate": "15/06/1990",
"day": 15,
"month": 6,
"year": 1990
}
}
Server route para consulta de CPF
No SvelteKit, as server routes (arquivos +server.ts ou +server.js) executam no servidor, protegendo a chave de API. Crie o arquivo src/routes/api/cpf/[cpf]/+server.ts:
import { json, error } from '@sveltejs/kit';
import { CPFHUB_API_KEY } from '$env/static/private';
import type { RequestHandler } from './$types';
interface CPFData {
cpf: string;
name: string;
nameUpper: string;
gender: string;
birthDate: string;
day: number;
month: number;
year: number;
}
interface CPFHubResponse {
success: boolean;
data?: CPFData;
}
export const GET: RequestHandler = async ({ params }) => {
const cpf = params.cpf.replace(/\D/g, '');
if (cpf.length !== 11) {
throw error(400, 'CPF deve ter 11 dígitos');
}
try {
const response = await fetch(
`https://api.cpfhub.io/cpf/${cpf}`,
{
headers: {
'x-api-key': CPFHUB_API_KEY,
'Accept': 'application/json'
},
signal: AbortSignal.timeout(10000)
}
);
if (response.status === 401) {
throw error(500, 'Erro de configuração da API');
}
const dados: CPFHubResponse = await response.json();
if (!dados.success) {
throw error(404, 'CPF não encontrado');
}
return json({
success: true,
data: dados.data
});
} catch (err) {
if (err && typeof err === 'object' && 'status' in err) {
throw err;
}
throw error(500, 'Falha na consulta de CPF');
}
};
Componente Svelte de validação de CPF
Crie o componente src/lib/components/CPFValidator.svelte:
<script lang="ts">
let cpf = '';
let resultado: {
nome?: string;
nascimento?: string;
genero?: string;
} | null = null;
let erro = '';
let carregando = false;
function formatarCPF(valor: string): string {
const numeros = valor.replace(/\D/g, '').substring(0, 11);
if (numeros.length > 9) {
return numeros.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4');
} else if (numeros.length > 6) {
return numeros.replace(/(\d{3})(\d{3})(\d{1,3})/, '$1.$2.$3');
} else if (numeros.length > 3) {
return numeros.replace(/(\d{3})(\d{1,3})/, '$1.$2');
}
return numeros;
}
function handleInput(event: Event) {
const input = event.target as HTMLInputElement;
cpf = formatarCPF(input.value);
resultado = null;
erro = '';
}
async function validarCPF() {
const cpfLimpo = cpf.replace(/\D/g, '');
if (cpfLimpo.length !== 11) {
erro = 'CPF deve ter 11 dígitos.';
return;
}
carregando = true;
erro = '';
resultado = null;
try {
const response = await fetch(`/api/cpf/${cpfLimpo}`);
const dados = await response.json();
if (response.ok && dados.success) {
resultado = {
nome: dados.data.name,
nascimento: dados.data.birthDate,
genero: dados.data.gender === 'M' ? 'Masculino' : 'Feminino'
};
} else {
erro = dados.message || 'CPF não encontrado.';
}
} catch (e) {
erro = 'Erro ao validar CPF. Tente novamente.';
} finally {
carregando = false;
}
}
</script>
<div class="cpf-validator">
<label for="cpf-input">CPF</label>
<div class="input-group">
<input
id="cpf-input"
type="text"
value={cpf}
on:input={handleInput}
placeholder="000.000.000-00"
inputmode="numeric"
maxlength="14"
/>
<button on:click={validarCPF} disabled={carregando}>
{carregando ? 'Validando...' : 'Validar'}
</button>
</div>
{#if erro}
<p class="erro">{erro}</p>
{/if}
{#if resultado}
<div class="resultado">
<p><strong>Nome:</strong> {resultado.nome}</p>
<p><strong>Nascimento:</strong> {resultado.nascimento}</p>
<p><strong>Gênero:</strong> {resultado.genero}</p>
</div>
{/if}
</div>
<style>
.cpf-validator {
max-width: 400px;
}
.input-group {
display: flex;
gap: 8px;
}
input {
flex: 1;
padding: 8px 12px;
border: 1px solid #ccc;
border-radius: 6px;
font-size: 16px;
}
button {
padding: 8px 16px;
background: #2563eb;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
}
button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.erro {
color: #dc2626;
margin-top: 8px;
}
.resultado {
margin-top: 12px;
padding: 12px;
background: #f0fdf4;
border: 1px solid #22c55e;
border-radius: 6px;
}
</style>
Usando o componente em uma página
Crie ou edite src/routes/cadastro/+page.svelte:
<script>
import CPFValidator from '$lib/components/CPFValidator.svelte';
</script>
<h1>Cadastro</h1>
<CPFValidator />
Validação com SvelteKit form actions
Para formulários que usam form actions (progressive enhancement), crie src/routes/cadastro/+page.server.ts:
import { fail } from '@sveltejs/kit';
import { CPFHUB_API_KEY } from '$env/static/private';
import type { Actions } from './$types';
export const actions: Actions = {
validar: async ({ request }) => {
const formData = await request.formData();
const cpf = (formData.get('cpf') as string).replace(/\D/g, '');
if (cpf.length !== 11) {
return fail(400, { cpf, erro: 'CPF deve ter 11 dígitos' });
}
try {
const response = await fetch(
`https://api.cpfhub.io/cpf/${cpf}`,
{
headers: {
'x-api-key': CPFHUB_API_KEY,
'Accept': 'application/json'
},
signal: AbortSignal.timeout(10000)
}
);
const dados = await response.json();
if (!dados.success) {
return fail(404, { cpf, erro: 'CPF não encontrado' });
}
return {
sucesso: true,
dados: dados.data
};
} catch (e) {
return fail(500, { cpf, erro: 'Falha na validação' });
}
}
};
Validação local com store reativo
Crie um store Svelte para validação local de CPF em src/lib/stores/cpf.ts:
import { writable, derived } from 'svelte/store';
export const cpfInput = writable('');
export const cpfLimpo = derived(cpfInput, ($cpf) =>
$cpf.replace(/\D/g, '')
);
export const cpfValido = derived(cpfLimpo, ($cpf) => {
if ($cpf.length !== 11) return false;
if (/^(\d)\1{10}$/.test($cpf)) return false;
let soma = 0;
for (let i = 0; i < 9; i++) {
soma += parseInt($cpf[i]) * (10 - i);
}
let resto = (soma * 10) % 11;
if (resto === 10) resto = 0;
if (resto !== parseInt($cpf[9])) return false;
soma = 0;
for (let i = 0; i < 10; i++) {
soma += parseInt($cpf[i]) * (11 - i);
}
resto = (soma * 10) % 11;
if (resto === 10) resto = 0;
if (resto !== parseInt($cpf[10])) return false;
return true;
});
Boas práticas
-
Chave de API no servidor -- Use
$env/static/privatedo SvelteKit para garantir que a chave nunca seja exposta no cliente. -
Validação em camadas -- Valide os dígitos localmente no componente antes de chamar a server route.
-
Progressive enhancement -- Use form actions para que o formulário funcione mesmo sem JavaScript habilitado.
-
Feedback visual -- Mostre estados de carregamento, sucesso e erro de forma clara para o usuário.
-
Controle de consumo -- Desabilite o botão durante o carregamento para evitar requisições duplicadas. O CPFHub.io não bloqueia ao atingir o limite do plano — cobra R$0,15 por consulta adicional —, então evitar requisições desnecessárias protege tanto a experiência quanto o orçamento.
Perguntas frequentes
Como o SvelteKit protege a chave de API do CPFHub.io?
O SvelteKit separa código de servidor e cliente em tempo de build. Ao importar a chave via $env/static/private, o compilador garante que ela nunca seja incluída no bundle enviado ao navegador. Qualquer tentativa de usar uma variável static/private em um componente .svelte gera erro em tempo de build — uma proteção automática e auditável.
Posso usar a validação de CPF diretamente no componente Svelte, sem server route?
Não é recomendado. Chamar a API do CPFHub.io diretamente do frontend exporia sua chave de API ao navegador. A server route atua como proxy seguro: o componente Svelte chama /api/cpf/{cpf} (sua rota interna), e apenas o servidor conhece a x-api-key. Essa arquitetura também permite adicionar cache e rate limiting no servidor sem tocar no componente.
O componente funciona sem JavaScript habilitado no navegador?
Sim, quando implementado com form actions (o arquivo +page.server.ts). O SvelteKit suporta progressive enhancement nativamente: sem JavaScript, o formulário faz um POST tradicional e recebe a resposta do servidor; com JavaScript, a ação é interceptada e o resultado é exibido de forma reativa sem recarregar a página.
Como armazenar o resultado da validação de CPF no estado global da aplicação Svelte?
Use o store reativo cpfInput e cpfValido demonstrados acima como ponto de partida. Para estado global mais complexo — como compartilhar o resultado de validação entre múltiplos componentes —, armazene o objeto data retornado pela API em um writable store e acesse-o via $cpfStore em qualquer componente que importe o store. Consulte a documentação oficial do SvelteKit para padrões recomendados de gerenciamento de estado.
Conclusão
O Svelte e o SvelteKit oferecem uma experiência de desenvolvimento fluida para integrar validação de CPF, com componentes reativos, server routes seguras e form actions com progressive enhancement. A API do CPFHub.io complementa esse stack com um endpoint simples, resposta em ~900ms e planos que escalam do desenvolvimento à produção sem mudanças de código.
Cadastre-se em cpfhub.io — 50 consultas mensais gratuitas, sem cartão de crédito — e adicione validação de CPF ao seu projeto Svelte em menos de 30 minutos.
CPFHub.io
Pronto para integrar a API?
50 consultas gratuitas para testar agora. Sem cartão de crédito. Acesso imediato à documentação.
Sobre a redação
Redação CPFHub.io
Time editorial especializado em APIs de CPF, identidade digital e compliance no mercado brasileiro. Produzimos guias técnicos, análises regulatórias e tutoriais sobre LGPD e KYC para desenvolvedores e líderes de produto.



