Skip to content

Migrate the documentation deployment from Netlify to Cloudflare Workers - #1719

Open
qunabu wants to merge 3 commits into
developfrom
feature/cloudflare-docs-deployment
Open

Migrate the documentation deployment from Netlify to Cloudflare Workers#1719
qunabu wants to merge 3 commits into
developfrom
feature/cloudflare-docs-deployment

Conversation

@qunabu

@qunabu qunabu commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

Move the documentation site off Netlify and onto Cloudflare Workers, deployed as the hyperformula-docs Worker in the Handsontable account. Deployments are driven by Workers Builds with the Git integration configured on the Cloudflare side, so the repository carries no deployment workflow, API token or account secret:

Trigger Result
push to master production deployment (npx wrangler deploy)
push to any other branch, and every pull request preview at https://<branch>-hyperformula-docs.handsoncode.workers.dev, posted as a pull request comment (npx wrangler versions upload)

Production traffic keeps reaching the documentation through the hyperformula-website Worker, which proxies /docs*. Its DOCS_ORIGIN has to be repointed from https://hyperformula-docs.netlify.app to https://hyperformula-docs.handsoncode.workers.dev once this lands on master and a production build succeeds. Until then, Netlify keeps serving production.

Changes

  • wrangler.jsonc — serves the VuePress output as static assets. The asset directory is docs/.vuepress/dist, not docs/.vuepress/dist/docs, so every document keeps the /docs/ prefix it is built with.
  • worker/index.js — resolves directory URLs (/docs/, /docs/api/) and extensionless URLs, redirects /docs to /docs/, and serves the nearest 404.html. Combined with "html_handling": "none", .html URLs are served as they are instead of being redirected to extensionless URLs.
  • not_found_handling is deliberately left at "none". Any other value makes the asset router answer browser navigations (requests carrying Sec-Fetch-Mode: navigate) on its own, bypassing the Worker and turning every directory and extensionless URL into a 404 in browsers while plain requests still succeed.
  • docs/.vuepress/cf/_headers, docs/.vuepress/cf/_redirects — indefinite caching for the content-hashed /docs/assets/*, and a redirect from the asset root to /docs/ so preview URLs are usable at their root. script/prepare-cf-assets.js copies them into the root of the build output, where they have to sit.
  • package.jsondocs:build:cf (the Cloudflare build command), docs:deploy:cf, docs:preview:cf, and the wrangler dev dependency.
  • .nvmrc — Node.js 22, the version all CI workflows already use and the one the Cloudflare build image reads from this file. Wrangler also requires Node.js 20 or newer.
  • netlify.toml — removed.
  • DEV_DOCS.md — documents the deployment, the dashboard build settings and the manual commands.

Test plan

Verified against a production deployment built from this branch (npm run docs:build:cf + wrangler deploy, 480 assets). URL behaviour matches the Netlify site exactly:

URL Netlify Cloudflare Worker
/docs/ 200 200
/docs/api/ 200 200
/docs/guide/basic-usage.html 200, no redirect 200, no redirect
/docs/guide/basic-usage 200 200
/docs 301 to /docs/ 301 to /docs/, query preserved
/docs/nope 404 404 with the VuePress 404 page

Each row was checked both as a plain request and as a browser navigation (Sec-Fetch-Mode: navigate, Sec-Fetch-Dest: document), against the deployed preview.

  • npm run lint passes.
  • npm run docs:build:cf writes docs/.vuepress/dist/docs, _headers and _redirects.
  • /docs/assets/* is served with cache-control: public, max-age=31536000, immutable; documents keep max-age=0, must-revalidate.
  • sitemap.xml still lists https://hyperformula.handsontable.com/docs/... URLs.
  • The preview build for this pull request succeeds and its URL serves the documentation: https://feature-cloudflare-docs-deployment-hyperformula-docs.handsoncode.workers.dev/docs/
  • Every URL above returns the same status for a browser navigation as for a plain request, verified on the deployed preview.
  • develop merged in: npm run docs:build:cf succeeds on the merged tree and /docs/guide/built-in-functions.html (generated by the docs pipeline added on develop) is served.

Follow-up outside this repository

  1. Repoint DOCS_ORIGIN in the hyperformula-website project once this reaches master and a production build succeeds.
  2. Disconnect both Netlify projects: hyperformula-docs (production) and hyperformula-dev-docs (the deploy previews on this pull request). Deleting netlify.toml does not stop them, because their Git integration lives on the Netlify side.

🤖 Generated with Claude Code


Note

Medium Risk
This changes how production and preview documentation are built and served; URL routing depends on the new Worker and asset settings, and production still needs the separate hyperformula-website DOCS_ORIGIN cutover after deploy.

Overview
Moves the VuePress documentation site from Netlify to Cloudflare Workers (hyperformula-docs), with CI/deploy handled by Workers Builds rather than in-repo Netlify config.

Hosting and routing: Adds wrangler.jsonc (static assets from docs/.vuepress/dist), worker/index.js to mirror prior URL behavior (directory index.html, extensionless paths → .html, trailing-slash redirect, nearest 404.html), and docs/.vuepress/cf/_headers / _redirects (long-lived cache for hashed /docs/assets/*, root → /docs/). script/prepare-cf-assets.js copies those files into the dist root after build.

Tooling: New npm scripts docs:build:cf, docs:deploy:cf, docs:preview:cf; wrangler as a dev dependency; .nvmrc bumped to 22; .gitignore for Wrangler local state. netlify.toml is removed.

Docs: DEV_DOCS.md documents the Cloudflare deployment flow, dashboard settings, and manual commands.

Reviewed by Cursor Bugbot for commit b8542ec. Bugbot is set up for automated code reviews on this repo. Configure here.

Deploy the documentation site as the `hyperformula-docs` Cloudflare Worker,
driven by Workers Builds. The Git integration is configured on the Cloudflare
side, so no deployment workflow, API token or account secret lives in the
repository: pushes to `master` deploy production, pushes to any other branch and
every pull request upload a preview version with its own URL.

- `wrangler.jsonc` serves the VuePress output as static assets. The asset
  directory is `docs/.vuepress/dist`, not `docs/.vuepress/dist/docs`, so that
  every document keeps the `/docs/` prefix it is built with.
- `worker/index.js` resolves directory and extensionless URLs and redirects
  `/docs` to `/docs/`, while `"html_handling": "none"` keeps `.html` URLs served
  as they are. This reproduces the URL behaviour of the previous hosting.
- `docs/.vuepress/cf/_headers` caches the content-hashed assets indefinitely,
  `docs/.vuepress/cf/_redirects` points the asset root at `/docs/`. Both are
  copied into the build output by `script/prepare-cf-assets.js`, as they have to
  sit in the root of the asset directory.
- `.nvmrc` now selects Node.js 22, the version all CI workflows already use and
  the one the Cloudflare build image picks up from this file.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@netlify

netlify Bot commented Jul 31, 2026

Copy link
Copy Markdown

Deploy Preview for hyperformula-dev-docs ready!

Name Link
🔨 Latest commit b8542ec
🔍 Latest deploy log https://app.netlify.com/projects/hyperformula-dev-docs/deploys/6a6ce8398a05260008ab7a4b
😎 Deploy Preview https://deploy-preview-1719--hyperformula-dev-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Comment thread wrangler.jsonc
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 31, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
hyperformula-docs b8542ec Commit Preview URL

Branch Preview URL
Jul 31 2026, 06:27 PM

`not_found_handling: "404-page"` makes the asset router answer browser
navigations (requests carrying `Sec-Fetch-Mode: navigate`) on its own, without
invoking the Worker. Combined with `html_handling: "none"`, that turned every
directory and extensionless URL into a 404 in browsers, while plain requests
without the navigation headers kept working.

Leave `not_found_handling` at `"none"` so that requests matching no asset reach
the Worker, and serve the nearest `404.html` from there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8bf2585. Configure here.

Comment thread worker/index.js
Conflicts resolved as follows:

- `package.json` — kept the `docs:dev` and `docs:build` scripts from `develop`
  (they now generate the built-in function docs first) and added the
  `docs:*:cf` scripts on top of them.
- `package-lock.json` — regenerated from the `develop` lockfile.
- `DEV_DOCS.md` — kept the rewritten file from `develop` and moved the
  deployment description into its `Documentation` section.
- `.gitignore` — kept both sets of entries.
- `netlify.toml` — stays deleted. `develop` had corrected its publish directory
  and Node.js version, but the file is obsolete with the deployment on
  Cloudflare.
@qunabu

qunabu commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

@qunabu qunabu self-assigned this Jul 31, 2026
@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown

Performance comparison of head (b8542ec) vs base (ebaa2b2)

                                     testName |    base |    head | change
--------------------------------------------------------------------------
                                      Sheet A |   518.8 |  516.42 | -0.46%
                                      Sheet B |  172.29 |   172.8 | +0.30%
                                      Sheet T |  149.15 |  152.21 | +2.05%
                                Column ranges |  488.18 |  495.52 | +1.50%
                                Sorted lookup | 14478.7 | 14600.4 | +0.84%
Sheet A:  change value, add/remove row/column |   18.03 |   17.81 | -1.22%
 Sheet B: change value, add/remove row/column |  157.51 |  157.96 | +0.29%
                   Column ranges - add column |  166.02 |  166.26 | +0.14%
                Column ranges - without batch |  512.25 |  503.09 | -1.79%
                        Column ranges - batch |  130.29 |  127.22 | -2.36%

@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.31%. Comparing base (ebaa2b2) to head (b8542ec).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop    #1719   +/-   ##
========================================
  Coverage    97.31%   97.31%           
========================================
  Files          195      195           
  Lines        15734    15734           
  Branches      3456     3456           
========================================
  Hits         15312    15312           
  Misses         414      414           
  Partials         8        8           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant