Watch
1
0
Fork
You've already forked theknittingstudio.besthappypanda.com
0
The Knitting Studio — a free course in hand knitting. Static site served by bovine-pages-server. https://theknittingstudio.besthappypanda.com
  • HTML 89.1%
  • JavaScript 5.9%
  • CSS 4.9%
  • Shell 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Adam c30483b062 Link out to the three sister sites on their live domains
The header bar is back, now pointing at absolute URLs rather than relative
folder paths:

  justcook.besthappypanda.com
  modeltrains.besthappypanda.com
  backpack.besthappypanda.com

Since these are cross-origin, sync-from-dev.sh no longer strips the bar, and
the service worker's same-origin check already keeps them out of the cache, so
the sister-path guard in sw.js is gone as dead code.

Cache bumped to v5 so installed copies pick up the new header.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 07:51:04 +01:00
public Link out to the three sister sites on their live domains 2026-09-09 07:51:04 +01:00
tools Link out to the three sister sites on their live domains 2026-09-09 07:51:04 +01:00
.gitignore Publish The Knitting Studio as a bovine pages site 2026-09-08 16:13:24 +01:00
.pages Publish The Knitting Studio as a bovine pages site 2026-09-08 16:13:24 +01:00
README.md Link out to the three sister sites on their live domains 2026-09-09 07:51:04 +01:00

The Knitting Studio

A free course in hand knitting: illustrated diagrams, stitch charts, a stitch library and a curated set of video tutorials. Static HTML — no build step, no framework, no dependencies.

Live at https://theknittingstudio.besthappypanda.com

Layout

.pages           bovine-pages-server config (enables the site, sets the domain)
public/          everything that gets served
tools/           helper scripts, not published

Bovine serves the contents of public/ — nothing above it is web-visible.

Deployment

Hosting is bovine-pages-server on bovine.squarecows.com. Pushing to main is the deploy: the plugin reads the default branch directly, so there is no build or publish step.

The site is reachable two ways:

URL Notes
https://theknittingstudio.besthappypanda.com The live site.
https://adam.pages.sqcows.com/theknittingstudio.besthappypanda.com/index.html The pages URL. Visiting it is what registers the custom domain.

Why the repository is named after the domain

Bovine verifies domain ownership by checking a DNS TXT record containing sha256("owner/repository"). The TXT record on this domain was created for adam/theknittingstudio.besthappypanda.com, so the repository has to carry that exact name or verification fails and the custom domain silently 404s.

Gotcha: the pages URL needs an explicit filename

Because the repository name contains dots, bovine's directory-index logic reads .com as a file extension and does not fall back to index.html:

adam.pages.sqcows.com/theknittingstudio.besthappypanda.com/             -> 404
adam.pages.sqcows.com/theknittingstudio.besthappypanda.com/index.html   -> 200

This only affects the pages URL. The custom domain serves / correctly, because there the repository name is not part of the path. If you ever need to re-register the domain, hit the /index.html form.

Bringing the custom domain up

  1. DNS — point the hostname at the Traefik server: theknittingstudio.besthappypanda.com → A record to the bovine server's IP, or a CNAME to its hostname.

  2. Register — visit https://adam.pages.sqcows.com/theknittingstudio.besthappypanda.com/index.html once. That read of .pages is what writes the Traefik router into Redis and triggers the Let's Encrypt certificate. Until it happens the custom domain returns a bare 404 page not found.

  3. DNS verification is enabled on this instance, so the domain also needs a TXT record proving ownership, or registration is refused (silently — the pages URL still returns 200, the custom domain just never comes up):

    TXT theknittingstudio.besthappypanda.com
        bovine-pages-verification=6e2ded5ca8f03214570d54cdd899979db1ac49e5584aa2d15924e29ac12a431f
    

    This record is already in place. The hash is sha256("adam/theknittingstudio.besthappypanda.com"). If the repository is ever renamed or moved, recompute it and update DNS:

    printf '%s' "adam/theknittingstudio.besthappypanda.com" | shasum -a 256
    

Updating the site

The working copy lives in ~/Documents/knitting site, alongside three unrelated sites. To pull the knitting site across and rebuild public/:

sh tools/sync-from-dev.sh
git add -A && git commit -m "Update site" && git push

Sister sites

The header bar links out to the other three sites, each on its own domain and its own repository:

Site Domain
Cook Without a Recipe justcook.besthappypanda.com
The Model Railway Handbook modeltrains.besthappypanda.com
Pack Bench backpack.besthappypanda.com

These are absolute cross-origin links, so they are copied through by the sync script untouched. Earlier they were relative paths to folders in the dev directory, which is why the script used to strip the bar out.

One gotcha: the service worker cache

public/sw.js serves assets cache-first, so an edited stylesheet or script is invisible to anyone who has installed the app until the cache name changes. After changing anything under public/assets/, bump it:

const CACHE = "knitting-studio-v5";   // was v4

Installing as an app

The site is a PWA: it installs to the home screen on iOS (Safari → Share → Add to Home Screen), Android (Chrome → ⋮ → Install app) and desktop Chrome/Edge, and works offline once installed. Instructions with diagrams are on the home page under "Put it on your phone or tablet".

Credits

Every diagram, swatch and chart is inline SVG drawn in the page. Videos are embedded from YouTube and belong to the teachers who made them; nothing is hosted here.