Cloudflare Domain Redirect Rules from Root (@) to www Subdomain
It took me a bit of fiddling around to get 301 redirects working from the root (@
) of a domain to the www
subdomain.
For example, if I user requested https://gaurav.io/path/to/somewhere?foo=bar
, I’d want them to get a 301 Moved Permanently
redirect to https://www.gaurav.io/path/to/somewhere?foo=bar
.
CloudFlare offers powerful Redirect Rules that can get this done, but googling around community posts proved less than helpful on how exactly to get this done, especially on their free plan. So, might as well document it here since this blog (for now, at least) is powered using CloudFlare Pages with a custom domain (and that too for free, I might add 😬).
First off, you’d only want to associate one domain with the CloudFlare Pages deployment – the domain itself. It’s a mistake to treat domain.com
and www.domain.com
as two separate domain names. They might be two separate host names, but they’re the same domain name.
When you register domain.com
through a registrar (like GoDaddy, NameCheap, Google Domains, etc), you’re only paying for it once – you don’t need to pay and add your details again for pointing www.domain.com
somewhere if you’ve already registered and paid for domain.com
. So, this is a nice mental model to understand that domain names are domain.com
(or more generally, the $your-unique-name.$tld
scheme). Therefore, you just associate the domain.com
custom domain with your CloudFlare Pages deployment, the official documentation for which is quite straightforward.
To extend this mental model, when a user makes a request to a domain name, they generally do so to [subdomain]domain.com
(or more generally to ($subdomain.)?$your-unique-name.$tld
schema). When the subdomain
is missing, it is assumed to be the root/apex/naked/@
subdomain. By convention, the public website for a domain has historically been served on the www
subdomain (so www.domain.com
would serve the website for domain.com
), but there’s no hard rule around this.
I’m not sure if there’s any consensus around best practices, but I personally like all content on a domain name to be served via a subdomain – so, I still serve the default public website via the www
subdomain as has been the widely accepted historical convention. I know a lot of websites serve the default public website on the root subdomain, but I feel there’s something not quite right with it (while I can make some technical arguments around why it’s not a good idea, they’re strawman arguments at best, there’s nothing inherently wrong with it but to me it feels a little off).
In either case, whether you’re serving the default public website via the root subdomain or the www
subdomain (or something completely different like a blog
subdomain), what you really should be doing is setting up redirects so that the other possibilities redirect to the subdomain where you’re serving the content.
So, whenever someone (even an indexing bot) is assuming where you might be serving content, they at least get pointed to the right destination. Normally, in the self hosted scenario, you can point subdomains (including the @
subdomain) to your server using A
records and then your web server/proxy like Nginx can handle the redirect.
In our case, CloudFalre offers powerful Redirect Rules for managed domains that can perform the same redirect for us. In our case, we need a single rule that has the incoming condition as:
(http.request.full_uri wildcard "https://domain.com/*")
and has a Dynamic forwarding expression of:
concat("https://www.domain.com", http.request.uri)
with a status code of 301
and Preserve query string
checkbox ticked.
Once this rule is enabled, you should have the redirects working fine. This also works with their generous free plan (I tried initially with regex_replace
function which didn’t work because it needed a paid plan).