← Back to portfolio All case studies
Web design agency · Case study
The agency website that's also the agency's pitch
UK Web Marketing — this site. 86 pages of hand-coded Astro 6 on Vercel London, four regulated-vertical pillars, three honest tiers, and the EU-sovereign infrastructure thesis that drives every client build.
- Astro 6
- Vercel London (lhr1)
- Hand-coded CSS
- Resend EU
- Capsule CRM
- @astrojs/sitemap
- satori + resvg
The site you’re reading is the same site I’d build for you. Same stack, same posture, same maths. Treating it as a case study isn’t recursive vanity — it’s the only honest demo I’ve got.
The brief I wrote for myself
UK Web Marketing’s pitch is EU-sovereign infrastructure for UK small businesses, hand-coded, three honest tiers. Every line of that pitch sets a constraint:
- “EU-sovereign” — no US-resident SaaS on the critical client-data path
- “Hand-coded” — no Wix, no Squarespace, no WordPress, no Webflow
- “Three honest tiers” — Foundation £45, Growth Engine £195, Bespoke quoted, anchored to specific value (CRM, newsletter, articles)
- “For UK small businesses” — Pudsey-based, regulated verticals first (clinics, solicitors, schools, accountants)
The site has to be the pitch. A Vercel-hosted, Astro-built, schema-rich site quietly out-Lighthouses any agency competitor whose own site is a 4-second WordPress slog. That’s the demo.
The stack
Astro 6.3.8 with no JS framework. Astro ships near-zero JavaScript by default; the only client-side scripts are the analytics tag, the burger menu, the lead-magnet form, and the cookie-set logic on the notification bar. Everything else is server-rendered HTML.
Vercel London (lhr1). Every page renders from London edge POP. Vercel Analytics + Speed Insights run on first-party endpoints (/_vercel/insights/script.js) and set zero cookies — they don’t need GDPR consent.
Hand-coded CSS, no Tailwind. Tokens live in src/styles/global.css. The .related-card namespace is shared across the four Tier 1 vertical pillars; everything else is page-scoped via Astro’s built-in CSS scoping.
Resend EU for outbound mail. All form submissions (contact, audit, lead magnet) land in an EU-resident inbox via /api/lead.js (Vercel Edge function). No SendGrid, no Mailchimp.
Per-article OG images via Satori + Resvg. src/pages/og/[slug].png.ts generates a 1200×630 PNG per blog post at build time — brand gradient, EU-sovereign chip, dynamic title sizing, tag chips, all rendered from JSX through Satori’s SVG layer and into a PNG via @resvg/resvg-js. Cached immutable; never regenerated until the article’s frontmatter changes.
What 86 pages looks like
Routes break down roughly as:
- 18 blog posts (
src/content/blog/*.md) — 4 regulated-vertical pillars (clinic GDPR, solicitor SRA, school KCSIE, accountant ICAEW) + 4 buying-guide pairs (CRM, password managers, hosting, analytics) + 4 subscription-mechanics articles + the pillar long read - 4 Tier 1 vertical landing pages (
/clinics,/solicitors,/schools,/accountants) - 4 Leeds × Tier 1 combo pages (e.g.
/clinics-leeds) - 5 city pages (
/web-design-leedsplus Bradford / Manchester / Sheffield / York) - 6 industry pages generated from a dynamic
[vertical].astroroute - 4 TicketWave HQ integration spokes (
/integrations/{bookings,ordering,stock,ticketing}) - 5 legal pages (terms, privacy, refund, DPA, accessibility)
- 5 free-tool / marketing pages (
/audit,/domain-check,/start,/contact,/about) - The home page, the journal index, this case studies index, the FAQ, the glossary, the sitemap, the compliance posture, the lead-magnet flow
Every page emits structured JSON-LD: Organization + LocalBusiness + ProfessionalService singleton site-wide, BreadcrumbList per page, BlogPosting on articles, FAQPage on FAQ and pricing, Service + LocalBusiness on regulated-vertical pages, CollectionPage + ItemList on /work and this case-studies index.
The internal-linking architecture
The audit that drove PR #69 found two structural SEO problems: the four Leeds-combo pages had zero inbound internal links (orphaned), and the four Tier 1 pillars each had only one or two outbound internal links (broken hub-and-spoke).
The fix was two surfaces. The mega-menu added a Leeds × regulated practice column. Each Tier 1 vertical pillar grew an 8-card Related reading + pages block linking the matching pillar article, the Leeds combo, /compliance, /pricing, the DPA, and the three sibling Tier 1 verticals. Pages that previously dead-ended now link out ~9 times each, all to entity-bound contextual anchors.
This is the same hub-and-spoke shape I build for client sites — the work I’d usually charge for, exposed in the source tree so you can see what it looks like.
What “EU-sovereign” actually means
Vercel London hosts the rendered HTML. Cloudflare Email Routing forwards hello@ to an EU inbox. Resend (Ireland) sends outbound. Capsule CRM (Manchester, UK) is the contact graph. Stripe Payments Europe (Ireland) bills subscriptions. Plus Jakarta Sans is fetched from Google Fonts at build time, baked into the OG images, and served from Vercel from then on.
No US-resident SaaS on the critical client-data path. That’s the whole of the EU-sovereign claim. Every part of it is documented per-vendor on /compliance, with sub-processor disclosures matching what the DPA says. The same posture applies to every site I build — it’s not a feature, it’s the default architecture.
What’s deliberately missing
No A/B testing harness. No marketing automation funnel. No chat widget. No exit-intent popup. No live agent widget. No “we use cookies” banner because the site sets zero non-essential cookies. No paywall, no membership tier, no community feature. No mobile app.
The work that goes into a small-business site is the writing and the structure and the speed and the schema and the email flow — not the marketing tech. The site demonstrates that by being it.
What changed in the last 30 days
A 12-PR sprint shipped: positioning brief locked, three-tier pricing implemented, four regulated-vertical pillars launched, four Leeds × vertical combos, per-article OG image generation, blog index pillar clustering, legal pages refresh (privacy + terms + refund + new accessibility + new DPA), FAQ expansion with tier and EU-sovereign and regulated-practice sections, a copy audit sweep removing the last stale Cloudflare-as-host references, and an SEO audit sweep closing hub-and-spoke + adding LocalBusiness schema on the Leeds combos.
The pace is the point. Single developer, no agency overhead, hand-coded build, sharp brand voice in public/llms.txt so editorial agents stay on-message — three honest tiers, EU-sovereign, hand-coded, no corporate cliché.
If you want this for your business: WhatsApp me. Or compare the tiers.