One fun thing about having a personal domain is that you can keep the contents the same forever, but take a few days every so often to port it to some new stack you want to try out.
A while back, I had my site onGitHub PagesusingJekyll. This has long been the sort of default, go-to stack for me. At some point, I decided to simplify even further, and wrote a small script to take the few Markdown files I have and just make HTML out of them. I then usedNetlifyto do the hosting. I wanted to try out their legendary ease of use, and it was indeed super simple.
Earlier this year, Itook a job at Cloudflareto work on part ofCloudflare Workers. To get more familiar with the project I’d be working on,Workers KV, I came up with a plan: I’d put the Markdown files into KV, and then write a worker in Rust and WebAssembly that would generate the HTML on the fly, and run that in a Worker. This worked really well, even though it wasincrediblyoverkill for a simple static site.
Today we’re launching a new product,Workers Sites. You see, I wasn’t the only one who was interested in using Workers for static site hosting; I’d see tweets every so often where others were doing the same. But doing so was a completely manual process, you had to write the code on your own, you had to do all the setup yourself, and there was no assistance in doing so. Workers Sites changes this, and makes it easy to host your own site, if you’d like.
The rest of this post is going to walk you through my porting process forsteveklabnik.com.
I decided to go withZolafor my static site generator, as it’s written in Rust. I’d been wanting to give Zola a try for a while, and this was a good excuse to do so.
I needed these pre-requisites:
- Zola, instructionshere.
- Wrangler, instructionshere
- A Cloudflare Workers account,hereif you don’t have a Cloudflare account already, and if you do, you can click the Workers tab in your dashboard to set it up.
Additionally, you need to have a $ 5 / month subscription to Workers, to get access to Workers KV. I want us to offer a free tier of KV in the future, but we’re not there yet. That $ 5 / month gets you a lot more than one site, to be clear, but this isn’t a completely free solution today.
From there, it was time to make a new site with Zola:
>zola init steveklabnik.com>cd steveklabnik.com
Zola places the contents of your site in thecontents
directory. I only have one level for my site, so I dumped my two pages in there, as well as re-namedindex.md
to_ index.md
to follow Zola convention.
I had a few YAML headers on pages, I had to convert those to Zola’s TOML format:
title="Deleuzional" I really like the writing of [Gilles Deleuze]. I need
The
s are like---
in Jekyll, and the metadata is in TOML instead of YAML. I only neededtitle
because I am keeping things very simple.
I then needed to set up templates. Like most static site generators, the template forms the outer contents of the HTML on a page, and renders the Markdown into the middle somewhere. I have a slightly different template for my root than the other two pages, and Zola handles this pretty well.
>ls. templates Directory: C: Users Steve Klabnik src steveklabnik.com templates Mode LastWriteTime Length Name ---- ------------- ------ ---- -a ---- 9 / 25 / 2019 5: 28 PM 1288 index.html -a ---- 9 / 25 / 2019 5: 28 PM 1234 page.html
index.html
is for the root page, andpage.html
is for the other pages. This is a Zola convention.
Zola templates are written inTera, which is sorta likeLiquidorJinja2. Here’s a snippit of my template:
{{page.title}}
{{page.content | safe}}
The| safe
bit says that it shouldn’t escape the HTML produced bypage.content
, which is the rendered contents of the Markdown pages.
Finally, I have some static assets for the site: a CSS file, some JS, and the favicon, etc. These get dumped in thestatic
directory, and Zola will copy them over when I build the site.
Previewing during this process is very useful:
>zola serve
It took me a bit to figure out the conventions and get everything in place, and being able to change the contents and watch my browser refresh was invaluable.
Once I had my site ported to Zola, it’s time to deploy it to Workers Sites!
Wrangler is the command-line tool for Cloudflare Workers. If you haven’t used it before, you’ll have to log in:
>wrangler config
To check that your auth is set up correctly, you should run this command:
>Wrangler Whoami You are logged in with the email ' [email protected]'.
Of course, this should show your own email, not mine.
Let’s add Workers Sites to our project:
>wrangler init --site website
This creates two main things:wrangler .toml
, used to configure Wrangler, andworkers-sites
, a directory with your worker in it. I used the extrawebsite
parameter to wrangler becuase it defaults to the name of the subdirectory, and the period insteveklabnik.com
is invalid in a worker name, so I chosewebsite
. You can put whatever you’d like.
We need to set upwrangler. Toml
:
>code wrangler.toml
Mine looks like this:
account_id="f 5518 BFBF (C) a 64797 C 221 C7DA " name="website" type="webpack" route="www.steveklabnik.com/*" zone_id=" (b) c 46 ff9f5c 546203686794862 " workers_dev=false [site] bucket="./public" entry-point="workers-site"
All of these IDs are fine to be public;Wrangler
stores your sensitive stuff in~ / .wrangler
.
Important bits:
Theroute
needs to be set up properly; this one means that the worker will serve everything onwww.steveklabnik.com
. My account and zone IDs are needed; you can find these on the Cloudflare dashboard on the bottom right of the main page for it.workers_dev
is false; I’m deploying to my site, not to a subdomain ofworkers.dev
. If we did, we wouldn’t need thezone_id
, orroute
. Finally, thebucket
setting needs to be set to whatever your site generator’s output directory is, which for Zola ispublic
.
And that’s it! You can test out what this looks like:
>wrangler preview
If that all looks good, we can deploy:
>zola build>wrangler publish
And that’s it! And wow is it fast:
… well, we’realmostdone. Right now, this means I can only publish from my laptop. I’d prefer to have GitHub deploy this. We don’t have that as a built-in feature today, so I’d have to write an Action to do so. I haven’t yet, so I can’t blog about that. Maybe next time.
Additionally, there’s one more twist. Zola generates different URLs than my previous ones. I had previously had.html
on the ends of my pages, but Zola does not do this.
I think I’d prefer the new style anyway, so rather than figure out how to get Zola to do this, let’s set up some redirects. This is one cool thing about using Workers for this kind of task; while it’s slightly more manual, we can also make customizations very easily. The contents of the Worker that serves up the site lives inworkers-sites / index .js
. It’s very short.
import {getAssetFromKV} from "@ cloudflare / kv-asset-handler"; addEventListener ("fetch", event=>{ event.respondWith (handleEvent (event)); }); async function handleEvent (event) { try { return await getAssetFromKV (event); } catch (e) { let pathname=new URL (event.request.url) .pathname; return new Response (`" $ {pathname} "not found`, { status: 404, statusText: "not found" }); } }
Given that I only have two URLs, rather than doing something big and fancy, I did something dumb and straightforward:
import {getAssetFromKV} from "@ cloudflare / kv-asset-handler"; addEventListener ("fetch", event=>{ event.respondWith (handleEvent (event)); }); async function handleEvent (event) { // redirect some old URLs let pathname=new URL (event.request.url) .pathname; if (pathname==="/security.html") { return Response.redirect ("https://www.steveklabnik.com/security/", 301); } else if (pathname==="/deleuzional.html") { return Response.redirect ("https://www.steveklabnik.com/deleuzional/", 301); } try { return await getAssetFromKV (event); } catch (e) { let pathname=new URL (event.request.url) .pathname; return new Response (`" $ {pathname} "not found`, { status: 404, statusText: "not found" }); } }
I’m constructingpathname
twice here, but I just don’t care enough to bother to refactor this out. Additionally, it’s nice to purely add, rather than customize what was generated too much.
But with that, and anotherzola build && wrangler publish
, I have the redirects set up for my site.
GIPHY App Key not set. Please check settings