Skip to content

Wag

Wag is a site for a dog shelter or rescue: shelters, foster networks, breed rescues, municipal animal shelters and dog sanctuaries. Its pages are kraft paper with the dogs cut out of their photos and set on top, each on a soft blob in its own colour, with name tags shaped like dog tags, speech bubbles in a marker hand and paw prints. On the home page the dogs looking for a home walk in one at a time as you scroll, stop to say hello and trot off as the next one arrives. The demo is a fictional rescue, Second Chance Dog Rescue.

Wag comes in two variants, chosen when you create the site: files/Sanity (static pages, any host) and EmDash (--cms emdash, rendered on request on Cloudflare). The pages are the same in both.

Page Edit it in
Home Pages → Home page (a list of sections)
Dogs, adopt (steps, fee, questions), help (ways, donations, wishlist), happy tails, visit (opening hours), 404 Pages → the page’s own entry
Dogs (age, size, breed, good with, traits, story, photo, status, sponsorship) Content → Dogs
Happy tails Content → Happy tails
Name, charity details, address, navigation, header button, profiles Pages → Site settings
Buttons, labels, filters, chat, emails, game texts Content → Interface texts
Privacy, terms Pages → Legal

In headlines, words wrapped in *stars* get a marker stroke underneath that draws itself as they scroll into view, as in “Every dog deserves a *second chance*”.

Each dog is an entry with its age (as you’d say it, “about 3 years”) and age group, size, breed, when they arrived, whether they get on with children, cats and other dogs (yes, no or ask us), a few traits, a short summary, the line in their speech bubble and their story. The status is looking for a home, reserved or adopted; only dogs looking for a home walk in on the home page, and adopted ones stay on the dogs page, marked, until you remove them. The dogs page filters by size, age and who they get on with, with no JavaScript.

The photo is a cut-out: a PNG with a transparent background, the whole dog in frame, facing right. Remove the background with any tool (most phones’ photo apps do it) and export a PNG; it is served as AVIF or WebP with its transparency. The peeking dogs on the dogs and adopt pages are cut-outs of a head and front paws.

Everything works without keys; each feature switches on with its variables in .env.example.

Feature Where Service
Donate once, sponsor a dog monthly Help page (one-time Price ids), each dog’s page (a monthly Price id) Stripe
Book a meet-and-greet Adopt page, loads on click; a preview of the calendar until connected Cal.com
Newsletter, volunteer sign-up Home, happy tails and help pages, with a welcome email Supabase
Contact form Visit page; messages go to the email in Site settings Resend
AI chat On every page, answers about the dogs, adopting, helping and visiting; never promises a dog Claude
Search ⌘K or the search button: dogs, happy tails, adopt, help, visit built in, or Algolia
Analytics Every page; Google Analytics only after consent Plausible, Umami, Google Analytics

The home page is built from these sections, in any order: Meet them one by one (the dogs walking in), Our dogs (cards whose dogs hop out as you point at them), How to adopt (steps along a trail of paw prints), Ways to help (tags that swing in on their strings), In numbers, Happy tails (polaroids), Newsletter sign-up and Closing call. With reduced motion, the dogs stand in a row with their bubbles and nothing moves.

src/content/singletons/brand.json (Pages → Brand in Keystatic) holds three colors: the accent (collar red: buttons, paw prints and the marker underline), the second (tennis-ball yellow) and the third (sky blue), used for fills and the blobs under the dogs. Buttons are darkened until their white text is readable, the second and third are lightened until ink text on them is; a color that can’t get there stops the build with a message. Brand also sets the fonts (text, headings, and the marker hand for bubbles, tags and captions) and the corners. The site opens in the day theme (kraft paper) even when the visitor’s system is dark; the toggle switches to the night theme, a warm evening brown, and the browser remembers the choice.

Wag is ready for more languages: see Languages.

A small game, Which bowl?: a treat goes under one of three dog bowls, the bowls shuffle, faster every round, and you pick the bowl with the treat (tap it, or press 1, 2 or 3). Five rounds; the best score is kept in the visitor’s browser.

  • AGENTS.md describes the project for coding assistants (Claude Code reads it through CLAUDE.md, Cursor through .cursor/rules/).
  • /llms.txt lists your pages, dogs and happy tails for AI assistants, in every language.
  • Pages carry JSON-LD: the rescue as an AnimalShelter, the dogs as an ItemList, adopting as a HowTo, questions as a FAQPage, and each happy tail as a BlogPosting.
Terminal window
pnpm dev # local site, editor at /keystatic
pnpm build # production build
pnpm cms sanity schema|seed # move content to Sanity (see Content → Sanity)

In the EmDash variant: npm run dev, npm run deploy (Cloudflare) and npm run emdash:schema (after changing the content model).