Setting up Namecheap, Cloudflare, and Netlify the right way

After many years of always forgetting my configuration settings, I’m finally going to document my own unofficial tutorial on how setup Namecheap DNS with Cloudflare and Netlify. With this setup, I was finally able to achieve a perfect score in GTMetrix and the fastest my website ever loaded.

GTMetrix Perfect Website Score

My Current Stack

I use a static site generator called Hugo to build my website. All of the source files live in my private GitHub repo. Whenever I push a change to master (or ‘main’ as it’s now called), that kicks off the Netlify build process. It pulls in my master branch, and runs the hugo command which produces the public folder. That folder is then served from Netlify.

I buy all of my domains from Namecheap . I then link the domains to Cloudflare, which then points back to Netlify. Although Netlify doesn’t recommend putting another CDN in front of their CDN, it works out perfectly. Plus, I prefer the features of Cloudflare over Netlify. If only they had a CI/CD process of some sort.

Don’t use Apex Domains

What is an Apex domain? It’s basically your domain without the “www” part. Previously, I would always use https://bennettnotes.com , but that led to a problem. Apex domains can’t be used for CNAME records . That’s a problem for a couple of reasons. First, you have to hardcode an IP address in your DNS provider to point to. So I would have to hardcode Netlify’s IP address in Cloudflare. Secondly, they lose geo-targeting information .

So why does that matter? Well one day I happened to look at my TTFB (Time to first byte) for one of my webpages and saw that requests not served from Cloudflare’s cache was taking as much as 800ms!!

Slow TTFB for my website with Apex Domain on Netlify

After changing to not use an Apex domain, my TTFB was much better:

TTFB after removing Apex domain

After some digging, and coming across this post , it became clear that using the apex domain was the problem.

So don’t use Apex domains unless you really want to. Also, this doesn’t affect how you register your domain. Still buy your domain like you normally would. It just affects how you put it into Cloudflare.

Step 1: Setup Namecheap

First, setup your Namecheap domain. Go into your domain managment settings and set the custom domains to Cloudflare’s nameservers.

brenda.ns.cloudflare.com
noah.ns.cloudflare.com

Cloudflare Nameservers on Namecheap DNS

Step 2: Configure Cloudflare DNS

Next, setup Cloudflare to proxy requests to your Netlify website. First, add a CNAME record with the name www and the target being the netlify address of your website.

Namecheap DNS pointing to Netlify

Now we also need to setup a redirect form your Apex domain to the www subdomain. To do that, we first need to setup an A record with the name set to the value of @ (which will just fill in your domain name). The fun things is that it doesn’t really matter what the A record points to because we are redirecting it. So we can point it to Cloudflare’s internal documentation server 192.0.2.1.

Redirect Apex to www subdomain

Finally, let’s setup a page rule that will redirect https://mydomain/* to https://www.mydomain/$1. We use the variable $1 is so that if someone goes to https://mydomain/about we can redirect them to the new domain with the original path that they intended.

Redirect Page Rule

Step 3: Setup custom domain on Netlify?

To be honest, I don’t think this step is really needed, but I did it anyway. Go into your Netlify website and select the option to add a domain you own. After you go through the setup you might see a screen like this:

Setting up custom domain on Netlify

That’s it! This is how I have done it and it seems to be working well. I will update this guide if I find out anything else.

Extras

A couple of additional things I enabled for caching. Some of this might be redundant and overkill, but I wanted everything possible cached.

Cache Headers for Netlify

I inserted the following in my netlify.toml file:

[[headers]]
  for = "/images/*" # js files should be set this way
  [headers.values]
    Cache-Control = "public, max-age=604800"

[[headers]]
  for = "/*.webp" # js files should be set this way
  [headers.values]
    Cache-Control = "public, max-age=604800"


[[headers]]
  for = "/*.png" # js files should be set this way
  [headers.values]
    Cache-Control = "public, max-age=604800"

[[headers]]
  for = "/*.jpg" # js files should be set this way
  [headers.values]
    Cache-Control = "public, max-age=604800"


[[headers]]
  for = "/*.js" # js files should be set this way
  [headers.values]
    Cache-Control = "public, max-age=604800"

[[headers]]
  for = "/*.css" # css files too
  [headers.values]
    Cache-Control = "public, max-age=604800"

Cache Settings for Cloudflare

In Cloudflare, I enabled “Browser Cache TTL” and “Edge Cache TTL” for a day. I then set the “Cache Level” to everything.

Page Rules for Cloudflare Cache