Skip to content

Cloudflare DNS and CDN: The Base Configuration for Every FH Client Site

Every FH site sits behind Cloudflare. Here’s the exact configuration and why each setting is where it is.

John Cravey with EleviFounder6 min read

Every FH client site has Cloudflare in front of it. Not because Cloudflare is fashionable — because the free plan plus a $20/month Pro plan does five things a cheap shared host can’t: a fast global CDN, DDoS protection, free SSL with automatic renewal, basic WAF rules, and DNS that doesn’t go down. The same configuration runs on every site in the FH client book. Here’s exactly what it looks like.

Why Cloudflare and not the deploy platform’s default

Vercel and Netlify both run their own CDN. They’re fine. But they’re behind a single vendor — if that vendor has an outage, your site is down. Cloudflare in front means a second layer that can serve cached content even when the origin is down. We use Cloudflare in front of Coolify-hosted sites (where it’s essential — Coolify VPSes are single-region) and in front of Vercel-hosted sites too (for the bot-management and Turnstile features Vercel doesn’t bundle).

Step 1: nameservers

Move DNS to Cloudflare. Log in, add the domain, Cloudflare scans the existing DNS, gives you two nameservers to point your registrar at. The change propagates in 1–24 hours depending on the previous DNS TTL. Until the propagation is complete, leave the old DNS as-is — Cloudflare’s scan will have copied your existing records.

Step 2: DNS records

For a Next.js site deployed to Coolify:

  • A record: `@` → VPS IPv4, proxied (orange cloud).
  • AAAA record: `@` → VPS IPv6, proxied. If your VPS doesn’t have IPv6, skip.
  • CNAME: `www` → `@`, proxied.
  • MX records: whatever your email provider gave you (Google Workspace, Resend, etc.), DNS-only (gray cloud).
  • TXT: SPF, DKIM, DMARC for email. Don’t proxy.
  • TXT: domain verification records for Google Search Console, Microsoft 365, etc.

Proxy through Cloudflare (the orange cloud) means traffic to that record goes through Cloudflare’s network — CDN, WAF, bot management all apply. DNS-only (the gray cloud) means Cloudflare just returns the record without proxying. Always proxy your A/AAAA/CNAME for HTTP traffic. Never proxy MX or domain-verification records.

Step 3: SSL/TLS mode

Set to Full (Strict). This means Cloudflare connects to your origin over HTTPS, validates the origin’s certificate, and serves HTTPS to the visitor. The alternatives — Flexible, Full (non-strict), Off — are all worse in specific ways. Flexible serves cached HTTP from the origin over HTTPS to the user, which causes mixed-content bugs. Full (non-strict) accepts self-signed origin certs, which kills the trust chain.

For Coolify-hosted sites, install a Let’s Encrypt cert on the origin (Coolify’s built-in Caddy or Traefik does this) so Full (Strict) works. For Vercel-hosted sites, Vercel’s origin cert is valid and trusted by Cloudflare automatically.

Step 4: Always Use HTTPS + HSTS

Cloudflare’s “Always Use HTTPS” toggle redirects every HTTP request to HTTPS at the edge. Enable it. Then enable HSTS with at least a 6-month max-age and `includeSubDomains`. After a month of stability, increase to 12 months and add `preload`, then submit to the HSTS preload list.

Step 5: caching configuration

Cloudflare’s default cache rules cache static assets aggressively (images, CSS, JS) and pass HTML through to your origin. For a Next.js site with static HTML pages, this is fine — your origin (Coolify or Vercel) serves the HTML quickly enough that caching at Cloudflare provides marginal benefit.

If you want HTML cached at the edge too, use a Cache Rule that matches `request.uri.path matches "^/"`, sets cache eligibility to `Eligible for cache`, and sets edge TTL to whatever staleness you tolerate (we use 1 hour for static marketing pages). The origin still serves on cache misses.

Step 6: Brotli and HTTP/3

Both should be enabled (they are by default on Pro). Brotli compresses HTML/CSS/JS better than gzip. HTTP/3 is faster on lossy connections. Neither has a meaningful downside.

Step 7: page rules for redirects

Anything you’d use a Next.js `redirects()` config for, you can do faster at Cloudflare’s edge. Common ones:

  • Force www to apex: `www.example.com/*` → `https://example.com/$1`, 301.
  • Legacy URL redirects: `/old-path` → `/new-path`, 301.
  • Force HTTPS on a specific subdomain: `http://api.example.com/*` → `https://api.example.com/$1`, 301.

Edge redirects are sub-10ms. Application-level redirects through your Next app are 200ms+. For static redirect rules, always do them at Cloudflare.

Step 8: WAF rules

Cloudflare’s managed ruleset blocks the OWASP top 10 by default. On the free tier you get a basic ruleset; on Pro you get the more aggressive managed rules. We use Pro for any site that takes user input (a contact form is enough — bots find them quickly).

We add a few custom rules: rate-limit POST requests to `/api/*` and `/*/contact` to 10/minute per IP, challenge any request claiming to be from a known bot user agent that wasn’t allowlisted, block requests with no User-Agent header. Together these stop 90% of low-effort attacks.

Step 9: bot management

Cloudflare Pro includes basic bot management. The bot score is exposed as a request header, and you can write rules that challenge or block requests with low scores. For most SMB sites the default settings are fine — pair them with Turnstile on forms and you’re covered.

Step 10: monitoring

Cloudflare’s dashboard surfaces real-time traffic, threat events, cache hit ratio, bandwidth usage. We check it weekly across the client book. The two metrics that matter most: cache hit ratio (should be above 80% on static assets, 40%+ on HTML if you’ve enabled HTML caching) and threat events (zero is fine; a sudden spike is a signal).

When to add Cloudflare Workers

Not by default. Workers add complexity, and most of the things people reach for Workers for are better done in Next.js middleware or server actions. We add Workers when (1) we need behavior at the edge that has to happen before the Next app runs, like an A/B test variant selection that must persist across CDN cache layers; or (2) we need to manipulate response bodies at the edge for a specific route. Every other use case stays in the Next app.

Sites we DON’T put Cloudflare in front of

If a client is on Squarespace or another all-in-one builder where the platform handles SSL, CDN, and DDoS protection, adding Cloudflare in front creates more complexity than it solves. We respect the platform’s opinions on those sites and only use Cloudflare for DNS (DNS-only records, no proxy).

How this lands across FH client work

Every site we ship — BHR, james-marina, CabCarpentry, the Tivey site, fh-site itself — is behind Cloudflare with this exact configuration. Setup takes one afternoon. Maintenance is ten minutes a quarter checking the dashboard. Incidents prevented: every credential-stuffing attempt, every DDoS, every bot-scraping wave. If your site is hosted bare-metal or directly off a CMS without a CDN in front, book a consultation — adding Cloudflare is a free-to-cheap win every time.

Written by
John Cravey
Founder

Founder of Frontend Horizon. Writes most of the long-form work on the FH blog.

Newer post
Supabase Row Level Security: The Multi-Tenant Pattern We Use Across FH Clients
Older post
Google Search Console: From Zero to Actionable in an Afternoon
Keep reading

More from the blog

Next.js·6 min

Next.js 16.1 in Production: The Migration Playbook We Run on Every FH Site

Next 16.1 is the lean target. Here’s the exact migration we run, what breaks, and what to delete after.

Cloudflare·5 min

Cloudflare Pages vs Workers vs R2: Picking the Right Cloudflare Product

Cloudflare has 30+ products. Three of them cover 80% of what most SMB sites need.

Cloudflare·4 min

Cloudflare Turnstile: The CAPTCHA That Doesn’t Make Your Users Hate You

reCAPTCHA hurts conversion. Turnstile doesn’t. Here’s the wiring that keeps your forms spam-free without the click-the-bicycles ritual.