Deploy Your Static Website for Free with Cloudflare Pages

Every app developer needs a website. Whether it’s to host your privacy policy, showcase your apps, or serve your app-ads.txt file for ad networks, having a reliable web presence is essential. When I was setting up the website for my indie development brand, Atlantis Kid, I explored several hosting options. I ultimately chose Cloudflare Pages, and it’s been one of the best infrastructure decisions I’ve made.

Why Cloudflare Pages?

There are many free hosting options — GitHub Pages, Netlify, Vercel, Firebase Hosting — so why Cloudflare Pages? Here’s what sold me:

It’s Completely Free

Cloudflare Pages’ free tier is remarkably generous:

  • Unlimited sites
  • Unlimited bandwidth
  • 500 builds per month
  • Automatic HTTPS with free SSL certificates
  • Global CDN distribution

For an indie developer who doesn’t want to worry about surprise bills, this is hard to beat. I’ve been running my site for over a year without paying a cent for hosting.

Global CDN Performance

Cloudflare operates one of the world’s largest CDN networks with data centers in over 300 cities worldwide. Your static site is served from the edge location closest to your visitor, resulting in blazing-fast load times. My site loads in under 200ms from most locations.

Automatic HTTPS

Every site deployed to Cloudflare Pages gets a free SSL certificate automatically. No configuration needed, no certificate renewals to manage. Your site is served over HTTPS from day one.

Seamless Git Integration

Connect your GitHub (or GitLab) repository, and Cloudflare Pages automatically deploys whenever you push to your main branch. No CI/CD pipelines to configure, no deployment scripts to maintain.

Setting Up Your First Cloudflare Pages Site

Let me walk through the process I followed to deploy my developer website.

Step 1: Create a Cloudflare Account

If you don’t already have one, sign up at dash.cloudflare.com. The free plan is all you need.

Step 2: Prepare Your Repository

Your site needs to be in a GitHub or GitLab repository. For a simple static site (like my initial setup with just HTML and CSS), the structure might look like:

├── index.html
├── app-ads.txt
├── privacy/
│   └── balloon-pop.html
└── static/
    └── images/
        └── logo.png

For a Hugo site (which I later migrated to), the structure includes Hugo’s standard directories:

├── config/
│   └── _default/
│       └── hugo.toml
├── content/
│   └── en/
│       └── blog/
│           └── my-first-post.md
├── layouts/
├── static/
│   └── app-ads.txt
└── themes/

Step 3: Connect to Cloudflare Pages

  1. Log in to your Cloudflare dashboard.
  2. Navigate to Workers & Pages in the sidebar.
  3. Click Create application > Pages > Connect to Git.
  4. Authorize Cloudflare to access your GitHub account.
  5. Select the repository you want to deploy.

Step 4: Configure Build Settings

This is where things differ depending on your site type.

For a plain static site (no build step):

Framework preset: None
Build command: (leave empty)
Build output directory: /

This was my initial setup. Cloudflare simply serves the files as-is from the repository root. Dead simple.

For a Hugo site:

Framework preset: Hugo
Build command: hugo --minify
Build output directory: public

Cloudflare Pages has built-in support for Hugo and many other static site generators. It knows how to install Hugo and run the build process.

Step 5: Deploy

Click Save and Deploy. Cloudflare will pull your code, run the build command (if any), and deploy your site. The first deployment typically takes 1-2 minutes.

Your site will be available at https://your-project-name.pages.dev. You can use this URL immediately or set up a custom domain.

Configuring Hugo for Cloudflare Pages

Since I migrated my site to Hugo, let me share some specific configuration tips.

Hugo Version

Cloudflare Pages uses a default Hugo version that may not match what you’re using locally. To specify your Hugo version, set an environment variable in your Cloudflare Pages project settings:

Variable name: HUGO_VERSION
Value: 0.145.0

You can set this in Settings > Environment Variables in your Pages project. Make sure this matches the version you’re using locally to avoid build inconsistencies.

Base URL Configuration

In your hugo.toml (or config.toml), set the base URL to your production domain:

baseURL = "https://atlantiskid.com"

For preview deployments (which use a different URL), you can override this with an environment variable or use Hugo’s built-in --baseURL flag in your build command:

Build command: hugo --minify --baseURL $CF_PAGES_URL

The CF_PAGES_URL environment variable is automatically provided by Cloudflare Pages and contains the URL for the current deployment.

Content Organization

I organize my Hugo content with multilingual support:

content/
├── en/
│   ├── blog/
│   │   ├── my-first-post.md
│   │   └── flutter-tips.md
│   └── _index.md
└── zh-tw/
    ├── blog/
    │   └── my-first-post.md
    └── _index.md

This keeps content well-organized and makes it easy to add new languages later.

Setting Up a Custom Domain

A .pages.dev URL works fine, but a custom domain looks more professional. Here’s how to set one up:

If Your Domain Is Already on Cloudflare

  1. Go to your Pages project > Custom domains.
  2. Click Set up a custom domain.
  3. Enter your domain (e.g., atlantiskid.com).
  4. Cloudflare automatically configures the DNS records.

This is the easiest path because everything stays within the Cloudflare ecosystem.

If Your Domain Is Elsewhere

  1. Add a CNAME record pointing to your-project-name.pages.dev.
  2. Go to your Pages project > Custom domains and add your domain.
  3. Cloudflare will verify the DNS and provision an SSL certificate.

I recommend transferring your domain to Cloudflare’s registrar — they sell domains at cost with no markup. This simplifies DNS management and takes advantage of Cloudflare’s full feature set.

Setting Up Both Root and WWW

For the best user experience, configure both:

  • atlantiskid.com (root domain)
  • www.atlantiskid.com (www subdomain)

Add both as custom domains in your Pages project. Cloudflare handles the SSL certificates for both automatically.

Preview Deployments

One of Cloudflare Pages’ best features is automatic preview deployments. Every pull request or non-production branch push gets its own unique URL:

https://branch-name.your-project.pages.dev

This is incredibly useful for reviewing changes before merging to production. I use preview deployments to verify that new blog posts render correctly and that my site changes look right before pushing to main.

You can also share preview URLs with others for feedback without affecting your production site.

Environment Variables

Cloudflare Pages lets you set environment variables for your builds. Common uses include:

  • HUGO_VERSION: Pin your Hugo version (as mentioned above)
  • NODE_VERSION: If your build process uses Node.js
  • Custom variables: API keys or configuration values needed at build time

You can set different values for production and preview environments. Go to Settings > Environment Variables in your Pages project to configure them.

Important: Never put secrets that should remain private in your static site’s build output. Environment variables used during build time are safe (they’re not exposed in the output), but be careful with any values that might end up in client-side code.

Performance Benefits

Cloudflare Pages delivers impressive performance out of the box:

Automatic Optimizations

  • Brotli compression: All text-based assets are compressed automatically
  • HTTP/3: Supported by default for faster connections
  • Edge caching: Static assets are cached at edge locations worldwide

My Site’s Performance

After deploying to Cloudflare Pages, my site consistently scores 95+ on Google PageSpeed Insights. Here’s what contributes to that:

  1. Static HTML: No server-side rendering means instant responses
  2. Edge distribution: Content served from the nearest data center
  3. Minimal assets: I keep my site lean with inline CSS and minimal JavaScript
  4. Hugo’s minification: The --minify flag reduces HTML, CSS, and JS file sizes

For an app-ads.txt file that needs to be served quickly and reliably to ad networks worldwide, Cloudflare’s global CDN is perfect. Ad networks can verify your authorized sellers file instantly from any location.

Handling the app-ads.txt File

If you’re an app developer using AdMob or other ad networks, you need an app-ads.txt file at your website’s root. With Cloudflare Pages:

For plain static sites: Place app-ads.txt in your repository root. It will be served at https://yourdomain.com/app-ads.txt.

For Hugo sites: Place app-ads.txt in the static/ directory. Hugo copies everything from static/ to the output root during build:

static/
├── app-ads.txt
└── images/
    └── logo.png

After building, app-ads.txt will be available at https://yourdomain.com/app-ads.txt.

Comparing Cloudflare Pages to Alternatives

Feature Cloudflare Pages GitHub Pages Netlify Vercel
Free tier bandwidth Unlimited 100 GB/month 100 GB/month 100 GB/month
Build minutes 500/month 2000/month 300/month 6000/month
Custom domains Unlimited 1 per repo Custom Custom
Preview deployments Yes No (needs Actions) Yes Yes
Global CDN 300+ cities Limited Good Good
Free SSL Yes Yes Yes Yes

Cloudflare Pages stands out with unlimited bandwidth and its massive CDN network. For a developer website that might see traffic spikes when a new app launches, not worrying about bandwidth limits is valuable.

Troubleshooting Common Issues

Build Failures

If your Hugo build fails on Cloudflare Pages:

  1. Check the Hugo version. Make sure your HUGO_VERSION environment variable matches your local version.
  2. Check your theme. If your theme is a Git submodule, make sure it’s properly initialized. Cloudflare Pages handles submodules automatically, but check that the .gitmodules file is correct.
  3. Review the build logs. Cloudflare provides detailed build logs that usually pinpoint the issue.

Custom Domain Not Working

  1. DNS propagation: Allow up to 24 hours for DNS changes to propagate.
  2. SSL certificate: Cloudflare provisions SSL certificates automatically, but it can take a few minutes after adding a custom domain.
  3. Conflicting DNS records: Make sure there are no conflicting A or AAAA records for your domain.

404 Errors

For Hugo sites, make sure your baseURL is set correctly. A wrong base URL can cause all internal links to break.

Wrapping Up

Cloudflare Pages has been a reliable, performant, and genuinely free hosting solution for my developer website. The combination of unlimited bandwidth, a massive global CDN, automatic HTTPS, and seamless Git integration makes it an excellent choice for indie developers.

Whether you’re hosting a simple static site with your app-ads.txt and privacy policies, or running a full Hugo blog to support your AdSense application, Cloudflare Pages handles it effortlessly. The setup takes less than 10 minutes, and once it’s running, you can focus on what matters most — building great apps.

If you’re an app developer who hasn’t set up a developer website yet, I encourage you to start today. Cloudflare Pages removes all the friction of hosting, so the only thing standing between you and a professional web presence is creating the content itself.