After joining Cloudflare in April 2021, I recognized the amazing potential of Cloudflare Pages and all of its other products, so I decided to migrate my website from Netlify to Cloudflare (sorry Netlify – it was nice!).
My Personal Website#
Prep#
All my web content is located on my GitHub repository – you can create one for free today.
This can also be a simple index.html
file, and Cloudflare Pages will deploy and render it.
If you rather want to use a template, here a few interesting ones:
However, for this specific migration and my personal website, I used Hugo as Jamstack framework.
Step 0: Cloudflare Pages#
First, I created a FREE account on Cloudflare, and connected my GitHub repository with Cloudflare Pages.
I had to tweak the deployment a little by adding the build command:
hugo --gc --minify -b https://YOUR_DOMAIN.com/
Additionally, I had to set an Environment Variable to use the right version:
HUGO_VERSION 0.80.0
After that, the page deployed and worked just fine.
Step 1: DNS#
Now, go to dash.cloudflare.com
and add your custom domain. Choose the FREE plan for starters, and simply follow the next steps – which will be to change your domain’s Nameservers to Cloudflare’s in order to do a Full Setup and enjoy the full range of solutions and features; (alternatively, it’s also possible to do a CNAME Setup or Partial Setup).
On the DNS tab, add the following DNS records in order to connect to the page on Cloudflare Pages:
CNAME davidtofan.com CLOUDFLARE-PAGES.pages.dev Auto
CNAME www CLOUDFLARE-PAGES.pages.dev Auto
_Note: it’s recomended to use Page Rules to redirect www
to the domain apex when using Cloudflare Pages.
Make sure that there are orange cloud icons
Some other benefits of the orange cloud DNS records are:
- Masking your Origin IP
- Caching
- an HTTPS certificate on the edge servers (a separate certificate on your server is still necessary)
NOTE: only A, AAAA and CNAME records should have the orange cloud / be proxied. For non web traffic, such as TCP or UDP protocols, solutions such as Spectrum can help. Alternatively, a gray-cloud icon (DNS-only) does not proxy traffic.
Furthermore, I also added an empty MX record because I do not use this domain for emails nor do I want to receive emails, which is set to DNS-only:
MX davidtofan.com . Auto
Step 2: Domain#
In order to redirect www to davidtofan.com, go to Page Rules > Forwarding URL and set up the following Permanent Redirect Rule 301:
Matching URL:
www.davidtofan.com/*
Destination URL:
https://davidtofan.com/$1
Note: the DNS records need to be configured properly for this to work.
Then, I activated the DNSSEC function to add an extra layer of protection to my domain.
Step 3: Workers#
Now on to Workers – it’s simply amazing! You can deploy serverless code instantly across the globe.
I used this JavaScript template to create HTTP Security Headers for my website by using Workers:
let securityHeaders = {
"Content-Security-Policy": "default-src 'self'; upgrade-insecure-requests; script-src 'self' https://static.cloudflareinsights.com; img-src 'self'; object-src 'none'; form-action 'none'; base-uri 'self'; worker-src 'none'; connect-src 'self' https://static.cloudflareinsights.com/ https://cloudflareinsights.com/; child-src 'none'; frame-src 'none'; frame-ancestors 'none';",
"Strict-Transport-Security": "max-age=63072000; includeSubDomains; preload",
"X-XSS-Protection": "1; mode=block",
"X-Frame-Options": "DENY",
"X-Content-Type-Options": "nosniff",
"Referrer-Policy": "no-referrer",
"Permissions-Policy": "fullscreen=(self), autoplay=(), geolocation=(), microphone=(), camera=(), payment=(), interest-cohort=()",
"Access-Control-Allow-Origin": "https://cloudflareinsights.com/"
}
let sanitiseHeaders = {
Server: "My new server header"
}
let removeHeaders = [
"Public-Key-Pins",
"X-Powered-By",
"X-AspNet-Version"
]
addEventListener('fetch', event => {
event.respondWith(addHeaders(event.request))
})
async function addHeaders(req) {
let response = await fetch(req)
let newHdrs = new Headers(response.headers)
if (newHdrs.has("Content-Type") && !newHdrs.get("Content-Type").includes("text/html")) {
return new Response(response.body , {
status: response.status,
statusText: response.statusText,
headers: newHdrs
})
}
Object.keys(securityHeaders).map(function(name, index) {
newHdrs.set(name, securityHeaders[name]);
})
Object.keys(sanitiseHeaders).map(function(name, index) {
newHdrs.set(name, sanitiseHeaders[name]);
})
removeHeaders.forEach(function(name){
newHdrs.delete(name)
})
return new Response(response.body , {
status: response.status,
statusText: response.statusText,
headers: newHdrs
})
}
Don’t forget to add https://static.cloudflareinsights.com
to your script-src
directive and https://cloudflareinsights.com
to your connect-src
directive, in order to make Web Analytics work on Cloudflare.
Feel free to change any details and adapt it to your needs. If you need help with the Content Security Policy (CSP), then check out my other article.
Code source: The brand new Security Headers Cloudflare Worker
Alternative code: Set security headers - Workers
OCTOBER 2021 UPDATE: Cloudflare announced support for _headers
and _redirects
files. Simply create the files in the build directory of your project and within it, define the rules you want to apply.
For example, to prevent your pages.dev
deployment from being indexed and improve SEO, add the following to your _headers
file:
https://:project.pages.dev/*
X-Robots-Tag: noindex
More information here: Custom Headers for Cloudflare Pages
Step 4: Firewall#
Now we set up a Firewall Rule on the Firewall Tab > Firewall Rules, such as for example to block some python requests on my website:
(http.user_agent contains "python")
There are some interesting examples on Runcloud Blog.
Step 5: Results#
Finally, we analyze our website and check what has changed or improved:
- Cloudflare Diagnostic Center
- Security Headers
- Google PageSpeed Insights
- Google Mobile-Friendly Test
- Web Page Test
- DNSViz DNSSEC
- DNSSEC Analyzer
- GTmetrix
- Request Map Generator
- DNS Speed Benchmark
- Yellow Lab Tools
- SSL Labs
Conclusion#
2023 UPDATE: review the Migration Hub.
Comparisons from 2023 to 2024…