Para integrar validação de CPF em uma aplicação Qwik, use routeLoader$ para consultas server-side por parâmetro de URL e routeAction$ para processar submissões de formulário. A chave de API fica exclusivamente no servidor — nunca exposta ao cliente — e a resposta da CPFHub.io chega em cerca de 900ms com nome, data de nascimento e gênero do titular.
1. Pré-requisitos
-
Qwik configurado com
npm create qwik@latest. -
Node.js 18+ instalado.
-
Uma conta na CPFHub.io com sua chave de API gerada em
app.cpfhub.io.
2. Configure a variável de ambiente
Crie o arquivo .env na raiz do projeto:
CPFHUB_API_KEY=SUA_CHAVE_DE_API
O Qwik usa Vite, que carrega variáveis prefixadas com VITE_ no cliente. Como a chave de API deve ficar no servidor, use o prefixo sem VITE_ e acesse via process.env nos loaders e actions (que rodam no servidor).
3. Função utilitária de consulta
Crie o arquivo src/lib/cpfhub.ts:
// src/lib/cpfhub.ts
export interface CpfData {
cpf: string;
name: string;
nameUpper: string;
gender: string;
birthDate: string;
day: number;
month: number;
year: number;
}
export interface CpfResponse {
success: boolean;
data: CpfData;
}
export async function consultarCpf(cpf: string): Promise<CpfResponse> {
const cpfLimpo = cpf.replace(/\D/g, '');
if (cpfLimpo.length !== 11) {
throw new Error('CPF deve conter 11 dígitos');
}
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch(`https://api.cpfhub.io/cpf/${cpfLimpo}`, {
method: 'GET',
headers: {
'x-api-key': process.env.CPFHUB_API_KEY || '',
'Accept': 'application/json'
},
signal: controller.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
if (response.status === 401) throw new Error('Chave de API inválida');
throw new Error(`Erro HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
clearTimeout(timeoutId);
throw error;
}
}
4. Validação com routeLoader$
O routeLoader$ executa no servidor antes da renderização. Use-o para consultar um CPF passado na URL:
// src/routes/cpf/[cpf]/index.tsx
import { component$ } from '@builder.io/qwik';
import { routeLoader$ } from '@builder.io/qwik-city';
import { consultarCpf } from '~/lib/cpfhub';
export const useCpfData = routeLoader$(async (requestEvent) => {
const cpf = requestEvent.params.cpf;
try {
const resultado = await consultarCpf(cpf);
return { success: true, data: resultado.data, error: null };
} catch (error) {
return {
success: false,
data: null,
error: error instanceof Error ? error.message : 'Erro desconhecido'
};
}
});
export default component$(() => {
const cpfData = useCpfData();
return (
<div>
<h2>Resultado da validação</h2>
{cpfData.value.error && (
<p style="color: red;">{cpfData.value.error}</p>
)}
{cpfData.value.success && cpfData.value.data && (
<dl>
<dt>CPF</dt>
<dd>{cpfData.value.data.cpf}</dd>
<dt>Nome</dt>
<dd>{cpfData.value.data.name}</dd>
<dt>Gênero</dt>
<dd>{cpfData.value.data.gender === 'M' ? 'Masculino' : 'Feminino'}</dd>
<dt>Data de nascimento</dt>
<dd>{cpfData.value.data.birthDate}</dd>
</dl>
)}
</div>
);
});
Acesse http://localhost:5173/cpf/12345678900 para testar.
5. Validação com routeAction$ (formulário)
O routeAction$ processa submissões de formulário no servidor:
// src/routes/validar/index.tsx
import { component$ } from '@builder.io/qwik';
import { routeAction$, Form, zod$, z } from '@builder.io/qwik-city';
import { consultarCpf } from '~/lib/cpfhub';
export const useValidarCpf = routeAction$(
async (formData) => {
const cpf = formData.cpf;
try {
const resultado = await consultarCpf(cpf);
if (resultado.success) {
return {
success: true,
nome: resultado.data.name,
cpf: resultado.data.cpf,
genero: resultado.data.gender,
nascimento: resultado.data.birthDate
};
}
return { success: false, error: 'CPF não encontrado' };
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Erro na consulta'
};
}
},
zod$({
cpf: z.string().min(11, 'CPF deve conter pelo menos 11 caracteres')
})
);
export default component$(() => {
const action = useValidarCpf();
return (
<div>
<h2>Validar CPF</h2>
<Form action={action}>
<label for="cpf">CPF:</label>
<input
type="text"
id="cpf"
name="cpf"
placeholder="Digite o CPF"
maxLength={14}
required
/>
<button type="submit" disabled={action.isRunning}>
{action.isRunning ? 'Consultando...' : 'Validar'}
</button>
</Form>
{action.value?.error && (
<p style="color: red;">{action.value.error}</p>
)}
{action.value?.success && (
<dl>
<dt>Nome</dt>
<dd>{action.value.nome}</dd>
<dt>CPF</dt>
<dd>{action.value.cpf}</dd>
<dt>Data de nascimento</dt>
<dd>{action.value.nascimento}</dd>
</dl>
)}
</div>
);
});
6. Exemplo de resposta da API
A API da CPFHub.io retorna um JSON padronizado em todas as consultas:
{
"success": true,
"data": {
"cpf": "12345678900",
"name": "João da Silva",
"nameUpper": "JOÃO DA SILVA",
"gender": "M",
"birthDate": "15/06/1990",
"day": 15,
"month": 6,
"year": 1990
}
}
7. Endpoint de API puro
Se você precisa de um endpoint REST no Qwik (sem interface visual), crie um handler:
// src/routes/api/cpf/[cpf]/index.ts
import type { RequestHandler } from '@builder.io/qwik-city';
import { consultarCpf } from '~/lib/cpfhub';
export const onGet: RequestHandler = async ({ params, json }) => {
const cpf = params.cpf;
try {
const resultado = await consultarCpf(cpf);
json(200, resultado);
} catch (error) {
json(502, {
error: error instanceof Error ? error.message : 'Erro na consulta'
});
}
};
Teste com:
curl -X GET http://localhost:5173/api/cpf/12345678900 \
-H "Accept: application/json"
8. Boas práticas
-
Server-only —
routeLoader$,routeAction$eonGetrodam exclusivamente no servidor. A chave de API nunca é enviada ao cliente. -
Timeout — O
AbortControllercom 5 segundos impede que consultas lentas travem a renderização. -
Validação com Zod — Use
zod$norouteAction$para validar dados do formulário antes de consultar a API. -
Loading state — O Qwik expõe
action.isRunningpara mostrar feedback ao usuário durante a consulta. -
Plano gratuito — O plano gratuito oferece 50 consultas/mês. Ao ultrapassar o limite, a API não bloqueia: cobra R$0,15 por consulta adicional. Para produção, o plano Pro inclui 1.000 consultas por R$149/mês.
Perguntas frequentes
Como o routeLoader$ difere de um fetch direto no componente Qwik?
O routeLoader$ executa no servidor antes da renderização, garantindo que a chave de API nunca seja exposta ao cliente. Um fetch direto no componente rodaria no browser e exporia credenciais. Além disso, o loader permite pré-carregar dados para o componente antes de ele ser renderizado, melhorando a performance percebida.
A latência da API impacta a performance do Qwik?
A CPFHub.io responde em aproximadamente 900ms. Como o routeLoader$ roda no servidor (onde a latência de rede é menor do que a do usuário final), o impacto na experiência é reduzido. Use o AbortController com timeout de 5 segundos como proteção contra casos excepcionais de lentidão.
Como tratar o caso em que a API retorna erro no routeLoader$?
Envolva a chamada em try/catch e retorne um objeto com success: false e uma mensagem de erro. O componente pode checar cpfData.value.error para exibir feedback ao usuário — sem lançar exceções que interromperiam a renderização da página inteira.
O plano gratuito é suficiente para rodar a integração em desenvolvimento?
Sim. O plano gratuito oferece 50 consultas mensais sem cartão de crédito, o que cobre com folga o desenvolvimento e os testes iniciais. A ANPD recomenda que dados de identificação sejam tratados com base legal clara — o que se aplica tanto em desenvolvimento quanto em produção.
Conclusão
O Qwik com routeLoader$ e routeAction$ oferece uma forma segura e eficiente de integrar a API da CPFHub.io. A separação clara entre código de servidor e cliente elimina o risco de vazamento de credenciais, enquanto a abordagem de resumabilidade do Qwik garante que apenas o JavaScript necessário seja carregado no browser.
Para começar, crie sua conta gratuita em cpfhub.io, gere sua chave de API e siga os exemplos deste artigo. O plano gratuito cobre o desenvolvimento completo — você só escala para um plano pago quando seu produto estiver em produção com volume real.
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.



