Como integrar validação de CPF em aplicações Remix com loaders

Aprenda a integrar a API de consulta de CPF da CPFHub.io em aplicações Remix usando loaders e actions para validação server-side.

Redação CPFHub.io
Redação CPFHub.io
··7 min de leitura
Como integrar validação de CPF em aplicações Remix com loaders

Para integrar validação de CPF em aplicações Remix, use um módulo .server.ts para centralizar a chamada à API da CPFHub.io com a chave de autenticação no header x-api-key, depois exponha os dados via loader (consulta por URL) ou via action (formulário POST). A chave nunca chega ao navegador, e o log de cada consulta fica disponível para auditoria no servidor.

1. Pré-requisitos

  • Remix (v2+) configurado com npx create-remix@latest.

  • A chave de API da CPFHub.io

  • Node.js 18+ (para suporte nativo a fetch).


2. Configure a variável de ambiente

Crie o arquivo .env na raiz do projeto:

CPFHUB_API_KEY=SUA_CHAVE_DE_API

3. Crie o serviço de consulta

Crie um módulo utilitário para centralizar a chamada à API:

// app/services/cpfhub.server.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;
    }
}

O sufixo .server.ts garante que esse código nunca será enviado ao navegador.


4. Validação via loader (consulta por URL)

Crie uma rota que recebe o CPF via parâmetro de URL e retorna os dados validados:

// app/routes/cpf.$cpf.tsx
import { json, type LoaderFunctionArgs } from '@remix-run/node';
import { useLoaderData } from '@remix-run/react';
import { consultarCpf } from '~/services/cpfhub.server';

export async function loader({ params }: LoaderFunctionArgs) {
    const cpf = params.cpf;

    if (!cpf) {
    throw new Response('CPF não informado', { status: 400 });
    }

    try {
    const resultado = await consultarCpf(cpf);
    return json(resultado);
    } catch (error) {
    throw new Response(
    error instanceof Error ? error.message : 'Erro na consulta',
    { status: 502 }
    );
    }
}

export default function CpfPage() {
    const resultado = useLoaderData<typeof loader>();

    return (
    <div>
    <h2>Resultado da validação</h2>
    {resultado.success ? (
    <dl>
    <dt>CPF</dt>
    <dd>{resultado.data.cpf}</dd>
    <dt>Nome</dt>
    <dd>{resultado.data.name}</dd>
    <dt>Gênero</dt>
    <dd>{resultado.data.gender === 'M' ? 'Masculino' : 'Feminino'}</dd>
    <dt>Data de nascimento</dt>
    <dd>{resultado.data.birthDate}</dd>
    </dl>
    ) : (
    <p>CPF não encontrado.</p>
    )}
    </div>
    );
}

Acesse http://localhost:3000/cpf/12345678900 para testar.


5. Validação via action (formulário)

Para cenários com formulário de entrada, use uma action:

// app/routes/validar-cpf.tsx
import { json, type ActionFunctionArgs } from '@remix-run/node';
import { Form, useActionData } from '@remix-run/react';
import { consultarCpf, type CpfResponse } from '~/services/cpfhub.server';

interface ActionData {
    resultado?: CpfResponse;
    error?: string;
}

export async function action({ request }: ActionFunctionArgs) {
    const formData = await request.formData();
    const cpf = formData.get('cpf') as string;

    if (!cpf) {
    return json<ActionData>({ error: 'CPF é obrigatório' }, { status: 400 });
    }

    try {
    const resultado = await consultarCpf(cpf);
    return json<ActionData>({ resultado });
    } catch (error) {
    return json<ActionData>({
    error: error instanceof Error ? error.message : 'Erro na consulta'
    }, { status: 502 });
    }
}

export default function ValidarCpfPage() {
    const data = useActionData<typeof action>();

    return (
    <div>
    <h2>Validar CPF</h2>

    <Form method="post">
    <label htmlFor="cpf">CPF:</label>
    <input
    type="text"
    id="cpf"
    name="cpf"
    placeholder="Digite o CPF"
    maxLength={14}
    required
    />
    <button type="submit">Validar</button>
    </Form>

    {data?.error && <p style={{ color: 'red' }}>{data.error}</p>}

    {data?.resultado?.success && (
    <dl>
    <dt>Nome</dt>
    <dd>{data.resultado.data.name}</dd>
    <dt>CPF</dt>
    <dd>{data.resultado.data.cpf}</dd>
    <dt>Data de nascimento</dt>
    <dd>{data.resultado.data.birthDate}</dd>
    </dl>
    )}
    </div>
    );
}

6. Exemplo de resposta da API

A API da CPFHub.io retorna um JSON estruturado com os dados do titular conforme registrado na Receita Federal:

{
    "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. Tratamento de erros com ErrorBoundary

O Remix permite tratar erros de loader e action com ErrorBoundary:

// Adicione no mesmo arquivo da rota
export function ErrorBoundary() {
    return (
    <div>
    <h2>Erro na validação</h2>
    <p>Não foi possível consultar o CPF. Tente novamente em alguns instantes.</p>
    </div>
    );
}

8. Boas práticas

  • Sufixo .server.ts — Use para módulos que contêm a chave de API, garantindo que o código nunca chegue ao cliente.

  • Timeout — O serviço usa AbortController com 5 segundos de timeout para evitar loaders travados. A latência média da API é de ~900ms; dimensione o timeout com margem.

  • Validação local — Valide o formato do CPF (11 dígitos) antes de chamar a API para economizar consultas.

  • ErrorBoundary — Implemente ErrorBoundary em todas as rotas para exibir mensagens amigáveis ao usuário.

  • Cota e excedente — O plano gratuito da CPFHub.io inclui 50 consultas por mês. Ao ultrapassar o limite, a API não bloqueia: cada consulta extra custa R$ 0,15. Para volumes maiores, o plano Pro oferece 1.000 consultas/mês por R$ 149.


Perguntas frequentes

Como o Remix mantém a chave de API segura no servidor?

O sufixo .server.ts faz o Remix excluir automaticamente esse módulo do bundle do cliente durante o build. Isso garante que process.env.CPFHUB_API_KEY e a lógica de chamada à API jamais cheguem ao navegador. Qualquer tentativa de importar um módulo .server.ts em código de cliente resulta em erro de build antes do deploy.

Qual a diferença entre usar loader e action para validar CPF no Remix?

O loader é executado em requisições GET e é ideal quando o CPF vem como parâmetro de URL — por exemplo, em rotas de perfil ou verificação de cadastro. A action é executada em submissões de formulário (POST) e é a abordagem certa quando o usuário digita o CPF em um campo. Ambos rodam exclusivamente no servidor, portanto a chave de API nunca fica exposta.

Quanto tempo a API leva para responder e como isso afeta o loader?

A API da CPFHub.io tem latência média de ~900ms. O loader do Remix aguarda a resolução da promessa antes de renderizar a página, então configure um timeout razoável — o exemplo acima usa 5 segundos via AbortController. Para não penalizar a UX em consultas lentas, considere usar defer do Remix para carregar os dados de CPF em paralelo com o restante da página.

Como garantir conformidade com a LGPD ao usar a API de CPF no Remix?

Use o CPF apenas para a finalidade declarada ao titular, armazene apenas o necessário nos logs do servidor e implemente controle de acesso a esses registros. A ANPD orienta que dados de identificação devem ser tratados com o princípio da necessidade. No Remix, evite serializar dados de CPF no loader além do estritamente necessário para a view — o que não é enviado ao cliente não pode ser exposto.


Conclusão

O Remix é uma escolha sólida para integrar APIs de validação como a CPFHub.io porque o modelo loader/action garante que a chave de API e a lógica sensível nunca abandonem o servidor. Com o módulo .server.ts, o timeout via AbortController e o ErrorBoundary configurado, você tem uma integração robusta pronta para produção em menos de uma hora.

Para começar agora, crie sua conta gratuita em cpfhub.io, gere a API key no painel e faça a primeira consulta. O plano gratuito inclui 50 consultas por mês sem cartão de crédito — suficiente para validar a integração completa antes de decidir por um plano pago.

CPFHub.io

Pronto para integrar a API?

50 consultas gratuitas para testar agora. Sem cartão de crédito. Acesso imediato à documentação.

Redação CPFHub.io

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.

WhatsAppFale conosco via WhatsApp