This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
pnpm dev- Start development server with turbo modepnpm build- Build for productionpnpm start- Start production serverpnpm lint- Run ESLintpnpm test- Run all tests (Vitest)pnpm test:watch- Run tests in watch modepnpm vitest run __tests__/lib/utils.test.ts- Run a single test filepnpm vitest run -t "test name"- Run a specific test by name
Headless WordPress starter using Next.js 16 App Router with TypeScript.
- All WordPress REST API interactions centralized here
- Type definitions in
lib/wordpress.d.ts(Post, Page, Category, Tag, Author, FeaturedMedia) - Two fetch patterns:
wordpressFetch(throws on error) vswordpressFetchGraceful(returns fallback) WordPressAPIErrorclass for consistent error handling- Cache tags for granular revalidation:
['wordpress', 'posts', 'post-{id}', 'posts-page-{n}'] - Pagination via
getPostsPaginated()returns{ data, headers: { total, totalPages } } - Default cache: 1 hour (
revalidate: 3600) - Graceful degradation: builds succeed even when WordPress is unavailable
- Dynamic:
/posts/[slug],/pages/[slug] - Archives:
/posts,/posts/authors,/posts/categories,/posts/tags - API:
/api/revalidate(webhook),/api/og(OG images)
- Server Components with parallel
Promise.all()calls generateStaticParams()usesgetAllPostSlugs()for static generation- URL-based state for search/filters via
searchParams - Debounced search (300ms) in
SearchInputcomponent - Next.js 15+ async params pattern:
params: Promise<{ slug: string }>
- WordPress plugin sends webhook to
/api/revalidate - Validates
x-webhook-secretheader againstWORDPRESS_WEBHOOK_SECRET - Calls
revalidateTag()for specific content types (posts, categories, tags, authors) - Also calls
revalidatePath("/", "layout")for full site refresh
site.config.ts- Site metadata (domain, name, description)menu.config.ts- Navigation menu structure (mainMenu,contentMenu)next.config.ts- Image remotePatterns, /admin redirect to WordPress, standalone output
Local copy of craft-ds (v0.3.2) providing layout primitives:
Section- Page sections with vertical paddingContainer- Max-width container with horizontal paddingArticle- Prose container for WordPress content (max-width prose)Prose- Typography styles for rich contentBox- Flex/grid layout with responsive props
lib/utils.ts-cn()function for merging Tailwind classes (clsx + tailwind-merge)lib/metadata.ts-generateContentMetadata()for SEO metadata,stripHtml()for excerpt cleaning
- Vitest with
@path alias matchingtsconfig.json - Tests mirror source structure:
__tests__/lib/utils.test.tstestslib/utils.ts - Tests cover:
lib/utils,lib/metadata,lib/wordpress,api/revalidate - WordPress API tests mock
global.fetchto avoid external calls
- Strict typing with interfaces from
lib/wordpress.d.ts - Async params:
params: Promise<{ slug: string }>(Next.js 15+ pattern)
- Components: PascalCase (
PostCard.tsx) - Functions/variables: camelCase
- Types/interfaces: PascalCase
- Pages:
/app/**/*.tsx - UI components:
/components/ui/*.tsx(shadcn/ui) - Feature components:
/components/posts/*.tsx,/components/theme/*.tsx - WordPress functions must include cache tags
WORDPRESS_URL="https://example.com" # Full WordPress URL
WORDPRESS_HOSTNAME="example.com" # For Next.js image optimization
WORDPRESS_WEBHOOK_SECRET="secret-key" # Webhook validation
- Next.js 16 with React 19
- Tailwind CSS v4 with
@tailwindcss/postcss - shadcn/ui components (Radix primitives)
- craft-ds for layout (
Section,Container,Article,Prose)