Overview
We moved the Vel Tech Blog to Cloudflare Pages so that Hugo builds run on Cloudflare’s infrastructure and the published site sits behind their global CDN. The final architecture has three layers:
- Hugo generates the static HTML in CI.
- Cloudflare Pages serves production and preview deployments.
- Cloudflare Workers sit in front to add caching rules, redirects, and optional API endpoints.
This post walks through each step, the exact commands we ran, and the rationale behind the settings so you can reproduce or adapt the workflow.
Prerequisites
- Cloudflare account with Pages + Workers enabled.
- GitHub repository containing your Hugo project (PaperMod theme in our case).
- Hugo extended v0.146.0+ installed locally to test changes before pushing.
1. Configure Hugo locally
Install Hugo extended and confirm the binary is available. We prefer downloading the release tarball rather than using a package manager to avoid lagging versions.
| |
Update the global configuration (hugo.toml) to match what the Cloudflare build will need:
buildFuture = trueso future-dated posts show up in staging builds.baseURL = "https://<your-pages-domain>"to ensure absolute URLs resolve once deployed.- Theme-specific parameters (PaperMod profile, hero copy, etc.).
Run hugo server --buildFuture locally to verify the profile card, homepage layout, and RSS feeds look right before pushing.
2. Update the Hugo project
With PaperMod we made three repo-level adjustments so the Cloudflare build output matches the local preview:
- Homepage layout: Added
layouts/index.htmlto render the profile widget followed by the chronological list of posts. Without this override PaperMod would hide the profile on multi-post homepages. - Profile content: Populated the author image, LinkedIn link, and subtitle in
configParams.profileMode. When you update these values locally they will sync to every new deployment automatically. - Asset pipeline: Stored the avatar SVG and hero background inside
assets/so Hugo’s pipes fingerprint them. This matters because Cloudflare caches aggressively; fingerprinting busts cache when assets change.
Commit the changes and push to your main branch. Cloudflare Pages watches GitHub, so every push will trigger a build.
3. Cloudflare Pages deployment
Inside the Cloudflare dashboard create a new Pages project and connect it to the Hugo repository. Use the following settings:
- Production branch:
main(or whichever branch you consider stable). - Build command:
hugo --gc --minify. - Build output directory:
public. - Environment variable:
HUGO_VERSION=0.146.0so the build uses the same version as local development.
After saving, Cloudflare kicks off the initial production deployment plus a preview deployment for each pull request. You can monitor build logs directly in the dashboard to catch missing dependencies or misconfigured paths.
Configuring previews
Previews inherit environment variables from production, but you can override values (e.g., BASE_URL=https://preview.example.pages.dev) if your theme needs it. Enable “Automatic Branch Deployments” to create a unique URL for every branch—useful for copy reviews or QA.
4. Add Cloudflare Workers functionality
Workers are optional but powerful for smoothing over static-site limitations:
- From the Pages project, open “Functions” to attach a Worker to the deployment. This automatically routes requests through the Worker before static files are served.
- Create a
functions/_middleware.ts(or.js) file to inject HTTP headers. Example: set long-lived caching for images and shorter caching for HTML. - For more complex use cases (API proxy, authentication) create a standalone Worker under Workers & Pages → Workers, then add a Routes entry that matches
/api/*and points to the Worker script.
Remember to bind environment variables or KV namespaces through the Worker settings if you need dynamic data.
5. Test and troubleshoot
- Validate builds locally:
hugo --gc --minifyshould succeed before pushing. If the command fails locally it will fail inside Pages too. - Check build logs: Cloudflare surfaces Hugo output along with resource usage. Missing theme files or incorrect output directory paths show up here.
- Purge cache: When changing assets or headers, use the Pages project → “Purge cache” button so the CDN refreshes immediately.
- Rollbacks: Pages keeps previous deployments. If a deployment misbehaves, click “Rollback” to point production back to the last known good build without changing Git history.
Final Notes
By combining Hugo’s fast static builds with Cloudflare Pages’ deployment automation and Workers’ edge logic, the blog ships as a static site but still supports custom caching, redirects, and lightweight APIs. Commit, push, and let Cloudflare handle the rest.