Content sites

Volunteer local news site with events and classifieds

Volunteer-written town news with editor approval, weekly email digest, events calendar, paid classifieds and SEO-focused static pages.

nextjstypescriptsanitystripevercel

Built 1 time, downloaded 0 times.

Install from your terminal

Run this in your project folder. It signs you in, shows what changes and asks before it overwrites a file.

npx claude-lab add volunteer-local-news-site-with-events-and-classifieds-4bddbf
10 filesDownload zip
CLAUDE.md
# Town news site

## Purpose

Small-town news site run on donations. Volunteers submit stories, an editor approves them, and readers subscribe to a weekly email. The site also has an events calendar and paid classifieds (a few euros each). SEO matters: local people find stories through search.

Full scope is in SPEC.md. The phased build plan is in PLAN.md.

## Stack

- Next.js App Router with TypeScript.
- Sanity v3 Studio with GROQ queries.
- Deploy to Vercel hobby tier or a similar static-first host.
- Stripe Checkout for classifieds.
- Email provider: YOUR_EMAIL_PROVIDER (placeholder, not chosen yet).

## Commands

Scripts are planned as dev, build, start, lint, typecheck and test. After scaffolding, replace these with the real script names and keep this list accurate.

- `npm run dev`: local dev server.
- `npm run build`: production build.
- `npm run start`: serve the production build (used by the verify smoke run).
- `npm run lint`
- `npm run typecheck`
- `npm test`
- `npx sanity schema extract` (only if used)

Before saying any task is done, run the verify skill.

## Content workflow

- Sanity document `story` has a status field: `draft | submitted | approved | published`.
- The public site fetches only `approved` or `published` stories.
- Volunteers get an Editor-limited Sanity role. Only the editor role can publish.

## Rendering and cost rules

- Prefer static generation with on-demand revalidation through a Sanity webhook.
- Avoid per-request server rendering on public pages.
- Use the Sanity CDN and `next/image` with sized images.
- No heavy client JS on article pages.
- Do not add paid services without asking.

## SEO rules

- Every page has `generateMetadata`, a canonical URL and an Open Graph image.
- JSON-LD: `NewsArticle` for stories, `Event` for events.
- Generate `sitemap.xml` and `robots.txt`.
- Use semantic HTML.

## Safety

- Never commit secrets.
- Env var names: SANITY_API_READ_TOKEN, STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, EMAIL_API_KEY.
- Real values go in `.env.local`. `.env.example` lists the names with placeholders only.
- Do not read `.env` or `.env.local` in a session.

## Privacy

- Subscriber emails are personal data under GDPR.
- Double opt-in for subscriptions.
- Unsubscribe link in every email.
- Never log email addresses.

## Classifieds

- A Stripe webhook must confirm payment before an ad is published.
- Ads expire automatically after a set number of days.
- Editors can remove any ad.

## Gotchas

- Sanity drafts have IDs prefixed `drafts.`. Public queries must filter them out.
- The webhook revalidation endpoint needs a shared secret.
- Stripe: test mode only until the editor signs off.

## Workflow

- Explore, plan, code, then verify.
- Use plan mode before each phase in PLAN.md.
- Use `/clear` between unrelated tasks and between phases.

## Review

@REVIEW.md
Use for my project