Deploy Hugo + Tailwind v4 to Cloudflare: Super Fast GitHub Workflow

January 13, 2026
3 min read
Deploy Hugo + Tailwind v4 to Cloudflare: Super Fast GitHub Workflow

So you want your Hugo site to fly, right? Like, blink-and-it’s-live kind of speed. I got you. We’re gonna set up a GitHub Actions workflow that takes your Hugo code (rocking Tailwind v4), builds it with the speed of light using pnpm, and yeets it onto Cloudflare Pages.

Here’s the breakdown on how to set this up for maximum speed and optimization. No fluff, just the good stuff. 🚀


Why this setup rocks

  • pnpm: It’s way faster than npm or yarn. It eats less disk space and installs dependencies like a hungry beast.

  • Cloudflare Pages: The CDN is insane. Your site loads instantly anywhere in the world.

  • Caching: We’re gonna cache your processed images so Hugo doesn’t have to rebuild them every single time. This is the speed hack.

  • Concurrency: If you push code twice rapidly, it cancels the first build so you don’t waste time.


The Secret Sauce (Your Workflow File)

Create a file in your repo at .github/workflows/deploy.yml and paste this bad boy in. This is the optimized code you asked for, tuned for Node 24 and pnpm.

YAML

name: Deploy Hugo + Tailwind v4

on:
  push:
    branches:
      - main

# Stops old builds if you push new code immediately. Saves time!
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          submodules: true
          fetch-depth: 0 # Needed for Hugo's .GitInfo

      - name: Setup pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9

      - name: Setup Node.js 24
        uses: actions/setup-node@v4
        with:
          node-version: 24
          cache: 'pnpm'

      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v3
        with:
          hugo-version: 'latest'
          extended: true

      # THIS IS THE GAME-CHANGER for your site
      # Caches resized images so Hugo doesn't rebuild them every time
      - name: Cache Hugo resources (images)
        uses: actions/cache@v4
        with:
          path: resources
          key: ${{ runner.os }}-hugo-resources-${{ hashFiles('content/**', 'assets/**') }}
          restore-keys: |
            ${{ runner.os }}-hugo-resources-

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Build Hugo site
        run: hugo --gc --minify
        env:
          HUGO_ENVIRONMENT: production
          HUGO_ENV: production

      - name: Deploy to Cloudflare Pages
        uses: cloudflare/pages-action@v1
        with:
          apiToken: ${{ secrets.CF_API_TOKEN }}
          accountId: ${{ secrets.CF_ACCOUNT_ID }}
          projectName: olimiah # Change this to your actual project name!
          directory: './public'

How to set it up (The Boring Stuff)

You need to give GitHub the keys to your Cloudflare kingdom.

  1. Get your Cloudflare Info:

    • Account ID: Go to your Cloudflare Dashboard URL. The ID is the gibberish text after dash.cloudflare.com/.

    • API Token: Go to My Profile > API Tokens > Create Token. Use the “Edit Cloudflare Workers” template (it works for Pages too).

  2. Add Secrets to GitHub:

    • Go to your GitHub Repo.

    • Click Settings > Secrets and variables > Actions.

    • Add a New Repository Secret: CF_ACCOUNT_ID.

    • Add another one: CF_API_TOKEN.

  3. Check the Project Name:

    • In the YAML code above, look for projectName: olimiah. Make sure that matches exactly what you named your project in Cloudflare Pages.

Why we did what we did

  • fetch-depth: 0: Hugo loves Git info (like “Last Modified” dates). If you don’t do this, all your dates will be wrong.

  • pnpm install --frozen-lockfile: This ensures the CI server installs exactly what you have on your machine. No surprises.

  • The Cache Step: Seriously, if you have a lot of images that Hugo processes (resizing, cropping), this step saves minutes off your build time. It reuses the work from the last build.

Recent Articles

Why Hugo is the best Static Site Generators in 2026

January 13, 2026

Thinking about building a site in 2026? Honestly, the “shiny object syndrome” is real with all these frameworks, but Hugo is still the low-key king for anyone who wants a site that just …

Windows 11 vs. The Linux Crew: Why It’s Time to Jump Ship

January 13, 2026

If you’re tired of Windows 11 acting like that one overbearing landlord who enters your apartment without knocking, it’s time we talk about Linux. Switching OSs sounds like a massive headache, but …

Upgrading openSUSE Leap 16.0 to Kernel 6.18 (LTS) via Backports

January 12, 2026

Look, openSUSE Leap 16.0 is awesome. It’s stable, it’s enterprise-grade, and it doesn’t crash. But sometimes, “stable” feels a little too much like “driving your …

Next.js vs WordPress: Scalability, Security & Membership Made Simple

January 12, 2026

Hello Boss, welcome to the game! If you’re just starting your tech journey, choosing between Next.js and WordPress is like picking your first car. Do you want a custom-tuned supercar that you build …

The AI Hype Is Hitting a Wall Now

November 12, 2025

I’ve been hearing the narrative for two years. Everyone thinks AI is coming for all the jobs, starting with programming. But I am a developer, and from where I stand, the hype is settling down. …

Don't Call AI "The Future" Until You Know This

November 12, 2025

The market is currently overflowing with hype about Artificial Intelligence. You hear it everywhere: AI is the new revolution, the new internet, the new electricity. Alongside this hype, there’s …