Skip to content
Fumiet

Back to blog

Ship an Astro 7 site with GitHub Actions and Cloudflare Pages

日本語で読む

How the Fumiet studio site builds with pnpm and deploys a static Astro 7 dist/ to Cloudflare Pages through GitHub Actions and Wrangler.

The Fumiet studio site is Astro 7 (static output) in a GitHub repo, deployed to Cloudflare Pages. This post describes the setup that is running today—not a generic tutorial stack.

Stack we use

Piece Choice
Framework Astro 7 / output: 'static'
Package manager pnpm
Node 22
Hosting Cloudflare Pages
CI GitHub Actions + wrangler pages deploy
Public URL https://fumiet.com (after DNS cutover)

Cloudflare’s native “install the GitHub app and build on Pages” path failed here with error 8000011. Deploying dist/ from Actions with Wrangler has been reliable instead.

Treat the project’s *.pages.dev host as staging. Do not use it as the public front door—point people and SEO at your custom domain (fumiet.com here).

What the repo needs

At minimum:

  1. An Astro project that produces dist/ via pnpm build
  2. site set in astro.config.mjs to the public domain (canonical URLs, sitemap, RSS)
  3. A GitHub repository (private is fine)
  4. A Cloudflare account and a Pages project

Fumiet also ships JA/EN locale routes and Content Collections (app YAML, blog Markdown) in the same static build. The blog does not need a server runtime.

Cloudflare Pages project

Create a Pages project in the dashboard.

We do not rely on Cloudflare to run the build. GitHub Actions uploads the artifact. Store these secrets in the repo (Settings → Secrets and variables → Actions):

  • CLOUDFLARE_API_TOKEN — token with permission to deploy Pages
  • CLOUDFLARE_ACCOUNT_ID — your account ID

Never commit the token value.

GitHub Actions workflow

On push to main (and on pull requests), the job roughly:

  1. Checks out the repo
  2. Sets up pnpm and Node 22
  3. Runs pnpm install --frozen-lockfile
  4. Runs pnpm build
  5. Runs npx wrangler@4 pages deploy dist --project-name=<your-project> …

Worth calling out:

  • Build on CI, upload only dist/
  • Pin Wrangler with npx wrangler@4 so the job does not depend on a global install
  • Pass --branch so Pages can distinguish preview vs production branches

Locally, the same artifact path is:

pnpm install
pnpm build
pnpm preview

After deploy

Check that:

  • Staging (Pages preview) shows /ja and /en as expected
  • Static routes (apps, blog, legal) are not 404s
  • Public links, site, OG, and canonicals use the production domain—not the preview host in copy or social posts

Keeping the apex on the old host until DNS cutover is a normal pattern. Harden content on staging, then point fumiet.com / www at Pages. Leave MX and unrelated wildcard records alone.

Publishing a blog post on this site

Posts live under src/content/blog/ja/ and src/content/blog/en/ as Markdown. Entries with draft: false appear in the index, RSS, and the header Blog link. Pair locales with translationKey.

Push to main and Actions rebuilds Pages. There is no CMS in this phase.

Takeaways

  • Static Astro 7 fits Cloudflare Pages well
  • When native Git integration fails, GitHub Actions + Wrangler is a solid path
  • Keep secrets in GitHub; deploy only the build output
  • Use the custom domain publicly; treat *.pages.dev as staging

That is enough to publish a small studio hub or product catalog safely. Questions: Contact.