# Building the practice website

> **A practice site has one job:** turn a visitor who's already curious (from a referral, a directory, or a search) into a booked consultation. Plain, fast, and clear beats beautiful and slow.

---

## What every practice site needs

- **Homepage:** who you help, in their words, in the first screen, and one clear button to book a consultation.
- **"Is this you?" / who I help:** the language bank from [ideal client discovery](https://toolkit.marcusberley.com/ideal-client-discovery/).
- **How I work:** what sessions are actually like.
- **About:** credentials, license, and a real photo.
- **Fees & insurance:** fee, out-of-network, superbills, cancellation policy, and a **Good Faith Estimate** notice for self-pay clients.
- **Contact / booking:** one path, to your electronic health record (EHR) system's booking or a scheduler. Avoid web forms that invite clinical details.
- **Footer:** license number, state(s) where you can see clients, and crisis line (988).

---

## Path A: Template builder (most people)

**Squarespace, Wix, or your EHR's built-in website.**

- **Cost:** roughly $15 to $30 a month plus a domain.
- **Time:** a weekend.
- **Good for:** anyone who doesn't want to maintain code, which is most therapists.
- **Watch out for:** slow pages from heavy image templates (resize photos before uploading), contact forms that collect clinical detail, and limited control over robots.txt and structured data.

## Path B: A fast custom static site

What I use for my own practice. It makes sense if you, or someone helping you (including an AI coding assistant), are comfortable with a code editor and GitHub.

| Layer | Choice | Why |
|---|---|---|
| **Framework** | [Astro](https://astro.build) (static output) | Pre-renders plain HTML; almost no JavaScript shipped to visitors |
| **Styling** | Tailwind CSS | Fast to write; consistent design tokens |
| **Content** | Markdown and YAML files in the repo, no content management system (CMS) | Edit a text file, push, done. Nothing to log into or keep patched. |
| **Hosting** | [Cloudflare Pages](https://pages.cloudflare.com) | Free for a site this size; auto-deploys on every push to GitHub; global content delivery network (CDN) |
| **DNS & email auth** | Cloudflare DNS (domain name system) | Same dashboard as hosting; see [email domain authentication](https://toolkit.marcusberley.com/email-domain-authentication/) |
| **Quality checks** | TypeScript checks, ESLint and Prettier, Playwright tests with axe accessibility checks | Catches broken pages and accessibility problems before they go live |

- **Cost:** domain only (about $10 to $20 a year). Hosting is free.
- **Time:** a few days to build with help; minutes per edit after that.
- **Result:** sub-second page loads, which help search ranking and visitors on phones.

### Worth copying regardless of stack

**Security headers.** On Cloudflare Pages, a `_headers` file in the site root sets them for every page:

```
/*
  X-Frame-Options: DENY
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin
  Permissions-Policy: camera=(), microphone=(), geolocation=()
  Strict-Transport-Security: max-age=31536000; includeSubDomains
  Content-Security-Policy: default-src 'self'; img-src 'self' data:; frame-ancestors 'none'; base-uri 'self'
```

(Loosen the Content-Security-Policy if you embed a scheduler, video, or analytics; each needs its domain allowed.)

**Structured data.** A small JSON-LD block tells Google you're a local health practice, with name, address or service area, and phone. Search "schema.org MedicalBusiness JSON-LD example."

**Images.** Serve modern formats (WebP/AVIF) sized to each screen. Astro's image component does this automatically; on a template builder, resize photos to about 2,000px wide before uploading.

**Accessibility.** Real text rather than text in images, alt text on photos, sufficient color contrast, and full keyboard use. It also helps search engine optimization (SEO).

**Old links.** Replacing an old site? Redirect old URLs to their new equivalents so referral and directory links keep working.

---

## Launch checklist

- [ ] Domain connected, HTTPS working
- [ ] Booking button works on a phone
- [ ] Fees, insurance, and cancellation policy match your Disclosure Statement exactly
- [ ] License number(s) and the states where you can see clients visible
- [ ] 988 crisis line in the footer
- [ ] Good Faith Estimate notice on the fees page
- [ ] Google Business Profile links to the site
- [ ] Directory profiles link to the site
- [ ] `robots.txt` and `llms.txt` published (see [AI search visibility](https://toolkit.marcusberley.com/ai-visibility/))
- [ ] Email authentication (SPF, DKIM, and DMARC) set up on the domain (see [email domain authentication](https://toolkit.marcusberley.com/email-domain-authentication/))
- [ ] Tested on a phone, on slow mobile data
