Test-data tool for developers and QA: generates, validates and formats CPFs. Static Astro site, content in Brazilian Portuguese, published at cpfaleatorio.com.
All calculation runs in the browser. There's no application server, API, or database — no CPF typed or generated ever leaves the user's machine.
| Route | Content |
|---|---|
/ |
CPF generator |
/validador-de-cpf |
CPF validator |
/formatador-de-cpf |
CPF formatter |
/como-validar-cpf |
How the check-digit algorithm works |
/codigo |
Reference implementations in 6 languages (tabs; /codigo#python opens one) |
/o-que-e-cpf, /perguntas-frequentes, /sobre, /privacidade, /termos, /404 |
Content and legal pages |
| Command | What it does |
|---|---|
npm install |
Installs dependencies |
npm run dev |
Dev server at localhost:4321 |
npm test |
Unit tests (node --test, no framework) |
npm run test:coverage |
Tests with a coverage report |
npm run check |
test + build — run after any change |
npm run build |
Builds the static site into ./dist |
npm run preview |
Serves the local build |
npm run deploy |
Build + deploy to Cloudflare Pages (needs wrangler login) |
npm run indexnow |
Notifies Bing/Yandex of the current sitemap |
Node 22.x or 24.x. Odd-numbered releases (like 23) aren't supported by Astro.
src/lib/cpf.ts Algorithm — generation, validation, formatting, mod 11. No DOM.
src/lib/cpf.test.mjs Tests, including the "every generated CPF is valid" property
src/lib/site.ts Site metadata, nav, footer, and URL canonicalization
src/lib/snippets.ts Reference implementations shown on /codigo
src/lib/ui.ts Shared class strings for the Geist design system
src/components/ Tools (generator, validator, formatter) and site chrome
src/pages/ Static pages
src/lib/cpf.ts is the single source of truth: the tools, the algorithm page, and the
tests all import from it, so the documentation can't drift from the implementation.
Design tokens are documented in DESIGN.md.
No UI framework. The interactive surface is a few forms, a textarea, and tabs — plain
scripts in .astro components are enough.
One landing page per tool. Generate, validate, and format each have their own URL
(/, /validador-de-cpf, /formatador-de-cpf) so each can rank for its own search.
No trailing slash in URLs. trailingSlash: 'never' with build.format: 'file', which
emits o-que-e-cpf.html. Cloudflare Pages serves it at /o-que-e-cpf and 308-redirects
the other forms to it.
Tax region, not state. The 9th digit encodes one of the Receita's ten tax regions, and
most regions group several states together (CE, MA, and PI share digit 3). The selector
groups states by region instead of repeating the wrong simplification competitors use.
Light/dark theme with no flash. ThemeToggle.astro reads localStorage in a
synchronous inline script in <head>, before first paint; with no saved choice, it
follows prefers-color-scheme. That inline script needs the hash Astro's CSP generates
(see below) to pass script-src 'self'.
Build with npm run build, output directory dist. The CSP (script-src, img-src,
etc.) is generated by Astro via security.csp in astro.config.mjs and emitted as a
<meta> tag on every page — including the hash for the inline theme script, which would
change on every edit if it were hand-maintained in _headers. public/_headers only
covers what a <meta> tag can't: frame-ancestors, X-Frame-Options, and the immutable
cache on /_astro/*. Because the CSP is only emitted in the build, verify UI changes with
npm run preview, not dev.
After the first deploy, confirm that /o-que-e-cpf/ and /o-que-e-cpf.html redirect to
/o-que-e-cpf. If the project is on Workers static assets instead of classic Pages, set
html_handling = "drop-trailing-slash" in wrangler.toml.