As of
Est. 

Running on Cloudflare Pages

🔌 You do not need a dedicated server to run a Jamstack site in the cloud.

My static site is hosted at Cloudflare. There are well-known alternatives for hosting SSG sites, such as Vercel or Netlify. They are all similar and can also be combined. The VitePress documentation covers deployment on Cloudflare, including the important warning not to enable HTML minification, which will break Vue hydration.

Build Triggers

My sites on Cloudflare are linked to projects on my GitLab account. Whenever I push my commits to GitLab, Cloudflare does a clean checkout of the sources and runs the build command (npm run build).

If successful, the generated static site is deployed to a Cloudflare domain. This domain in turn is DNS aliased as blog.ergberg.de.

As an alternative to the git triggers, pages also provides webhooks to start deployments. Each URL is specific for a combination of project and environment.

Both mechanisms have in common that you can only deploy the most recent commit on a branch, not an arbitrary tag.

Build Environments

Pages supports two environments: Preview and Production. The main branch of the repository is connected to the Production environment. All other branches belong to the Preview environment.

I usually commit to a git branch that I called development. This triggers deployments to the Preview environment. When I pull development onto the main branch, it triggers a Production build.

Software on the Build Server

The build command on the Cloudflare server is the same as for the local build:

bash
npm run build
npm run build

I've told Cloudflare that once the command is finished, the generated files can be found at docs/.vitepress/dist. That is what Cloudflare deploys.

Node.js on the Cloudflare build server defaults to an older version (v12.18.0), but can be configured to a more recent version. Actually I am using node v18.12.1 on my local development machine. That is too new for builds on Cloudflare. There I use v17.9.0. In the root directory of my project is a file called .node-version with the following content:

txt
17.9.0
17.9.0

This way Cloudflare knows what to install.

The SVG generation with dot requires graphviz to be installed. Is that a problem on Cloudflare Pages? No, it is not: Graphviz is installed and dot -V says:

txt
dot - graphviz version 2.38.0 (20140413.2041)
dot - graphviz version 2.38.0 (20140413.2041)

The other software packages required during the build, such as VitePress, Mermaid.js or Cytoscape.js are node.js modules and are automatically installed according to the specifications in the package.json file.

Workers & Functions

Cloudflare also offers ways to deploy handlers for HTTP requests. The basic concept is called Cloudflare Workers. Cloudflare Functions are build on top of the Workers. The main addition of Functions is the build-in router that maps URL paths and parameters to handler functions and their parameters.

Local development and deployment are supported by a CLI tool called wrangler.

On this website, I implemented the backend functionality for sending emails on the feedback form with workers.

Route Matching

Google Search was not very impressed with my Cloudflare Pages site. The crawler refused to follow the links. Its lame excuse was that the links didn't lead to original pages, but generated HTTP redirects.

When I got to the bottom of it, I found that https://blog.ergberg.tk/basics/pages.html indeed generates a 308 response.

sh
> curl -sI https://blog.ergberg.tk/basics/pages.html
HTTP/2 308
location: /basics/pages
...
> curl -sI https://blog.ergberg.tk/basics/pages.html
HTTP/2 308
location: /basics/pages
...

Although the HTML file on the server is named exactly as specified in the URL, Cloudflare serves the page under a URL without the .html suffix.

This is the expected behavior for Pages:

If an HTML file is found with a matching path to the current route requested, Pages will serve it. Pages will also redirect HTML pages to their extension-less counterparts: for instance, /contact.html will be redirected to /contact, and /about/index.html will be redirected to /about/.

Nice coincidence. While I'm still analyzing, others seem to have stumbled across similar issues. Starting with 1.0.0-alpha.6, VitePress offers a new configuration option to change the default link normalization.