Introduction

After building this site using Hugo static site generator, I decided to host it using Cloudflare pages. The process of deploying the site to Cloudflare pages is very simple and well explained on Cloudflare documentation at https://developers.cloudflare.com/pages/, so there is not much benefit in repeating it here.

However, after deployment, I did face a few difficulties when configuring my custom domain. I am adding here the details of these issues and how I addressed them.

Before diving into problems and their solution, I am going to define some names here. I’ll be using these names later in the article below.

So let’s say

  • The name of domain name of website that I am trying to host on Cloudflare pages is DOMAIN-NAME.com
  • The name of gitHub/gitLab repository created for the site is GIT-PROJECT-NAME
  • The name of unique subdomain generated by Cloudflare pages after successful deployment is GIT-PROJECT-NAME.pages.dev

Problem1: When adding root domain as custom domain

Problem Background : I have my custom domain registered with a different registrar instead of Cloudflare. So when I tried to add apex/root domain DOMAIN-NAME.com in custom domain, Cloudflare returned a message suggested that apex domain has to be in Cloudflare Zone before it can be used as custom domain. I was able to add the www subdomain www.DOMAIN-NAME.com to Cloudflare pages without any problem. (Both root domain, and www subdomain should be added)

Solution :

Step1: I added the site to Cloudflare (For documentation on how to add a site to cloudflare https://developers.cloudflare.com/fundamentals/get-started/setup/add-site/]).

Step2: I retried adding the root/apex domain in Custom domain in Cloudflare pages and followed through the steps. This time it was added successfully.

So what actually happened in the background with Cloudflare ?

Cloudflare uses a technique called CNAME flattening. Cloudflare explains this as "CNAME records normally can not be on the zone apex. We use CNAME flattening to make it possible."

A CNAME record is added in my site’s DNS settings.

The entries in DNS Settings looked like below

TypeNameContentProxy StatusTTL
CNAMEDOMAIN-NAME.comGIT-PROJECT-NAME.pages.devProxiedAuto
CNAMEwww.DOMAIN-NAME.comGIT-PROJECT-NAME.pages.devProxiedAuto

Normally, a root domain is added with A record in Type and the Ip address of the web server in Content. But with Cloudflare pages, it instead adds a CNAME record Type.

Also read, https://developers.cloudflare.com/pages/platform/custom-domains/#add-a-custom-apex-domain

Problem2: Multiple domains and subdomains now opens my website

Problem Background: So now my website is in production and accessible via multiple domains/subdomains i.e.

DOMAIN-NAME.com (I only want the website to be accessible using this root domain)

www.DOMAIN-NAME.com (I want to redirect users trying to access using www to root domain)

GIT-PROJECT-NAME.pages.dev (This subdomain is created by Cloudflare , I do not want to use this to access my website in production)

somecharacters.GIT-PROJECT-NAME.pages.dev (Cloudflare pages also creates a new unique subdomain for each deployment , I do not want any of these deployment subdomains to access my website in production)

Solution:

1- Redirecting all traffic from www.DOMAIN-NAME.com to DOMAIN-NAME.com

As the site is already added to Cloudflare (Step1 in Problem1 Solution) , so the easiest way to implement this is to create a Page Rule in Cloudflare. Cloudflare offers 3 Page-rules in free plan. We only need one. This Page rule can be created using following steps-

Step1: Go to the site in Cloudflare dashboard

Step2: Go to Rules section and then select Page Rules and click Create Page Rule. The Create Page Rule for dialog opens

Step3: Under the If the URL matches: heading, there is an input field URL (required).

In field 'URL (required)', enter 'www.DOMAIN-NAME.com/*'

Step4: Under the Then the settings are: heading, provide following inputs

In dropdown 'Pick a Setting (required)', select value 'Forwarding URL'
In dropdown 'Select status code (required)', select value '301-Permanent Redirect'
In field 'Enter destination URL (required)', enter 'https://DOMAIN-NAME.com/$1'

Step5: Click Save and Deploy Page Rule button

2- Handling GIT-PROJECT-NAME.pages.dev subdomain

Cloudflare pages currently do not offer any feature to remove this subdomain after adding a custom domain. After a little research on forms, I could find two potential options proposed.

Option 1: Setup Cloudflare Zero Trust Access to restrict access to GIT-PROJECT-NAME.pages.dev I played around with this option for some time and felt like it wasn’t the best option, and it didn’t work either. I am adding these two links which give an idea about my conclusion.

Link to Cloudflare Community Comment describing why this option is not very intuitive

Link to Cloudflare Community comment describing the issue I also faced and why this option didn’t work

So I ditched the option1

Option2: Set up a bulk redirect from GIT-PROJECT-NAME.pages.dev to DOMAIN-NAME.com

This option worked like a charm. Steps to set up bulk redirect

Step1: Go to the site in Cloudflare dashboard

Step2: Go to Rules section and then select Redirect Rules and click Create bulk redirect list.

Step3: Give some name to the list and click Next

Step4: Then on Add URLs section, click on link Or, manually add URL redirects

Step5: Enter following information

In the `source URL` field, enter `GIT-PROJECT_NAME.pages.dev/`. 
And in `target URL` field enter `https://DOMAIN-NAME.com`.
And in `Status` dropdown select `301`.

And in `Edit parameters`, uncheck the checkbox `Include Subdomains` 
(If this is not unchecked, it will prevent you from accessing specific deployments. 
But if this is what you want, then leave it checked. 
Otherwise, I have added steps to securely accessing in point 3 below)

Step6- Then complete the process through.

Some useful links with information on bulk redirect setup.

Cloudflare-community-forum-link1

Cloudflare-community-forum-link2

3- Handling access to Cloudflare pages deployment urls

The best solution to keep the ability to access the deployment URLs , while not letting just anyone to be able to use them to access the production site , is to set up Zero Trust Access for these URLs.

This will add a login access page for each of the URLS *.GIT-PROJECT-NAME.pages.dev , and only users who have login access can then access these deployment previews

The steps to step this up is very clearly documented on Cloudflare documentation. Link customizing-preview-deployments-access