This site runs on Cloudflare, and the only thing I pay for is the domain. Hosting, DNS, the HTTPS certificate, CDN and automatic deploys are all free on the free plan.
Below is the step by step exactly as it was done here, and why it’s worth having a site of your own.
Why have your own site
LinkedIn, X and Medium are great for reach, but your content lives in someone else’s house: the algorithm changes, the format changes, a post disappears from the feed in two days. A site on your own domain is the opposite:
- It’s your track record. What you studied, wrote and built lives in one place, organized your way, with permanent links.
- It’s proof, not a promise. A résumé says “I know Laravel”; a post explaining how Laravel’s container works shows it.
- It keeps you relevant. Writing forces you to actually understand things. Each post is a study note someone else can use too, and one you can link in an interview, a PR or a conversation.
- The domain is yours. As long as you renew it (R$ 40 a year), the address stays the same, even if you switch hosting tomorrow.
What’s paid and what’s free
| Item | Where | Cost |
|---|---|---|
Domain (.dev.br, .com.br…) |
Registro.br | R$ 40/year (under R$ 4/month) |
| DNS | Cloudflare | Free |
| Static site hosting | Cloudflare Pages | Free |
| HTTPS certificate | Cloudflare | Free, auto-renewed |
| CDN and DDoS protection | Cloudflare | Free |
| Automatic deploy on every push | Cloudflare Pages + GitHub | Free |
On the Pages free plan, requests to static assets are unlimited. The limits that matter are 500 builds per month, 1 build at a time, up to 20,000 files per site and 25 MiB per file. For a personal site, none of that ever becomes a problem.
Step by step
1. Register the domain on Registro.br
.br domains are registered at Registro.br. For developers, .dev.br is a nice option, and it’s what I used here (matheusandreatta.dev.br). You need a Brazilian CPF or CNPJ, and it costs R$ 40 a year, less than R$ 4 a month.
During registration you can keep the default DNS. You’ll replace it in step 3.
2. Add the domain to Cloudflare
Create a Cloudflare account, click Add a domain, enter the domain and pick the Free plan. At the end, Cloudflare shows you two nameservers to use. Here they were irma.ns.cloudflare.com and oswald.ns.cloudflare.com. Yours will have different names.
3. Point Registro.br’s DNS to Cloudflare
In the Registro.br panel, open the domain, go to DNS → Alterar servidores DNS and replace them with the two nameservers Cloudflare gave you.
Propagation can take anywhere from minutes to a few hours. Once it’s done, Cloudflare marks the domain as Active and starts answering its DNS.
4. Keep the site in a Git repository
Any static site generator works: Astro, Hugo, Next in export mode, or plain HTML. This site uses Astro + Tailwind. npm run build outputs everything to dist/, just HTML, CSS and a little JS, with no server.
Push the project to GitHub (or GitLab).
5. Create the Cloudflare Pages project
In the Cloudflare dashboard, go to Workers & Pages → Create → Pages → Connect to Git, authorize GitHub and pick the repository. In the build settings:
- Framework preset: Astro
- Build command:
npm run build - Build output directory:
dist
If your project needs a specific Node version (this one requires >=22.12), set the NODE_VERSION environment variable on the project.
After the first deploy, the site is already live on a *.pages.dev address.
A note on how it went here: the first attempt used Workers + Static Assets, with a
wrangler.jsoncand a custom deploy command. It works, but for a static site it’s extra configuration. I switched to classic Pages, which needs no Wrangler and deploys on its own on every push.
What if my site is just HTML, CSS and JS?
You don’t need Astro, Node or a build step. Steps 1, 2, 3, 6 and 7 stay the same; only the way you upload the files changes. There are two paths:
Option A: with Git (recommended). Put index.html and the rest of the files in a repository and connect it to Pages as in step 5, but with:
- Framework preset: None
- Build command: leave it empty
- Build output directory: the folder that contains
index.html(/if it’s the repository root)
You still get automatic deploys on every push and a preview URL per branch.
Option B: no Git, just drag the folder. In Workers & Pages → Create application → Drag and drop your files, name the project, drag the site folder in and click Deploy site. To update it, upload a new version of the folder to the same project.
Two caveats with option B:
- Browser upload accepts up to 1,000 files, up to 25 MiB each.
- A project created this way can’t be switched to Git later. If you ever want automatic deploys, you’ll have to create a new project and reconnect the domain.
If you like the terminal, you can do the same with npx wrangler pages deploy ./site-folder.
6. Connect the domain to the project
In the Pages project, open Custom domains → Set up a custom domain and add the root domain (matheusandreatta.dev.br) and www. Since the DNS is already on Cloudflare, it creates the records itself and issues the HTTPS certificate.
7. Tweaks worth making
- SSL/TLS → Edge Certificates → Always Use HTTPS: redirects every HTTP request to HTTPS.
- Protect the domain against email spoofing. If you don’t send email from the domain, publish a TXT record
v=spf1 -all. It tells the world that no server is allowed to send email on your behalf. This site uses exactly that. - Optional, also free: Cloudflare Web Analytics, cookie-free, to see visits, and Email Routing, to create a
contact@yourdomainthat forwards to your Gmail.
What day-to-day looks like
The workflow becomes plain Git:
- I write the post in Markdown.
- I push to
main. - Pages builds and publishes it in about a minute.
Branches other than main get their own preview URL, so you can review a change live before merging.
Checklist
- Domain registered on Registro.br
- Domain added to Cloudflare (Free plan)
- Registro.br nameservers pointing to Cloudflare
- Site in a Git repository (or an HTML folder for direct upload)
- Cloudflare Pages project connected to the repository
- Root domain and
wwwset up as custom domains - Always Use HTTPS enabled
- SPF
-allif you don’t send email from the domain