Struggling with Cloudflare
Workers & Pages
It’s not a secret that this little project of mine is hosted on Cloudflare Pages. Static content served on the edge with unlimited bandwidth — I mean, what else could I wish for? And it is great. Additionally, the number of features Cloudflare offers nowadays is nowhere near the times I first heard about them, when Cloudflare was “just a solution against DDoS.” I’ve known about Cloudflare Pages for some time. I’ve also known about Cloudflare Workers for some time. What I didn’t know is that those two are kind of merged together now…?
From what I understood, you can now upload and serve static assets within a standard Worker deployment. You gain the same advantages you get when deploying static content using Pages. It feels like Cloudflare prefers their users to use Workers instead of Pages, even for static content. And I’m wondering whether I should go down this path or not. Let’s imagine I’m going to add a little form to my site. I have two options: serve my static content using Pages and handle the form submission using something called Pages Functions, or switch completely to Workers, still serving my static content for free using static assets, with my dynamic server-side logic implemented in the Worker itself. It’s probably worth mentioning that Pages Functions actually run on Workers, and I didn’t dig deep enough to understand the actual difference. We’ll see when the time comes.
DNS, redirects, and other messy stuff
Cloudflare is generous enough to provide you with a *.pages.dev domain to access your static content from the public internet. Then, you can set your custom domain with a simple CNAME DNS record. However, using Cloudflare nameservers is necessary for a custom apex domain. As I didn’t purchase my domain through Cloudflare, I had to do some tweaking at my original registrar so I could move my configuration to Cloudflare. I was afraid my rules wouldn’t survive the transfer, as I had several already created (e.g., to access the Dokploy dashboard running on my VPS, or MX and TXT records for my custom email addresses), but everything went pretty smoothly.
So, it didn’t take long to have my static content available on my own domain. I’m not sure whether it’s necessary nowadays, but I’m used to making sites available both on the apex domain and the www subdomain. For the www subdomain, I like to set a redirect to the apex domain, which is important for SEO to avoid duplicate content. And so I did exactly that in the rules section of my domain’s Cloudflare dashboard. They even have a template called “Redirect from WWW to root,” which gave me a feeling this is still a thing to do. Redirect set within a few clicks, marked as active in the rules overview. I headed to www.perner.dev and the content was there — perfect. I like to double-check things, so I opened my Ghostty terminal emulator and ran a simple curl:
curl 'https://www.perner.dev' > /dev/null
Expecting the 301 HTTP status code. But 200 received. Weird.
After about an hour of checking DNS records, redirect rules, trying different settings, and eventually opting for Bulk Redirects, I found the problem. You see, custom domains can be set on a specific application directly. That’s how I actually started when setting my custom domain for this site, and it walked me through the process above. What I kind of forgot is that I had already set two custom domains for my Pages application (apex domain and www subdomain). And this setting takes precedence over my redirect rules set in a completely different part of the Cloudflare dashboard. Skill issue on my side, I guess — or maybe I should have read the docs more thoroughly. But based on similar issues posted on the Cloudflare community site, I wasn’t alone struggling with DNS and redirects for custom domains.
The last thing I wished for was to practically disable the original *.pages.dev domain provided by Cloudflare. This wish took me into Zero Trust waters, from which I ran away rather fast. Not ready for that yet. Fortunately, in the same way I’m redirecting the www subdomain to my apex domain, I could redirect the original notes-bnt.pages.dev to perner.dev as well. Just like for the www subdomain, this is duplicate content mitigation. I’m not sure whether crawlers could possibly discover the original Cloudflare domain to scrape it, but if they do, they’ll now receive a proper permanent redirect.