This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is a Next.js-based static blog for Tech Tavern, LLC, configured for GitHub Pages deployment. The project uses MDX for blog posts and is designed to generate static output.
- Static Site Generation: Uses Next.js with
output: "export"for GitHub Pages - Blog System: Date-based URL structure
/blog/YYYY/MM/DD/slug/with MDX posts incontent/posts/ - Post Processing: Uses gray-matter for frontmatter parsing, with required fields:
title,date,slug - MDX Integration: Configured with remark-gfm, rehype-slug, and rehype-autolink-headings plugins
- Styling: Tailwind CSS v4 with PostCSS integration
# Development
npm run dev:webpack # Start development server
npm run dev:watch # Dev server with MDX change notifications
# Build and Deploy
npm run build # Build static site to /out directory
npm start # Start production server (after build)
# Code Quality
npm run lint # Run ESLint with Next.js and TypeScript rules
npm run typecheck # TypeScript type checking without emit
# Testing
npm run test # Run Jest tests
npm run test:watch # Run Jest tests in watch mode
# Content Creation
npm run new-article # Interactive script to create new MDX articlecontent/articles/*.mdx- Blog posts with date-prefixed filenames (YYYY-MM-DD-slug.mdx)src/app/articles/[year]/[month]/[day]/[slug]/page.tsx- Dynamic blog post pagessrc/lib/posts.ts- Post metadata extraction, URL generation, and Zod schema validationsrc/lib/env.ts- Environment variable validation using Zodsrc/mdx-components.tsx- Global MDX component stylingscripts/new-article.js- Interactive article creation script
Posts must have frontmatter with:
title: string(required)date: string(yyyy-mm-dd format, required)slug: string(required)- Optional:
excerpt,tagsarray,featuredImage,ogTitle,ogDescription,ogImage,canonicalUrl,draftboolean
Frontmatter is validated using Zod schema at build time for type safety.
- TypeScript: Strict mode enabled with path aliases (
@/*→src/*) - ESLint: Configured with Next.js core-web-vitals and TypeScript rules
- Testing: Jest with React Testing Library, jsdom environment
- Images: Unoptimized for static export compatibility
- Environment: Uses Zod validation for SITE_URL and NEXT_PUBLIC_BASE_PATH
- Content: MDX with gray-matter frontmatter parsing, reading time calculation (~200 wpm)
- Security: CSP headers configured in root layout
- URLs: Date-based structure
/articles/YYYY/MM/DD/slug/
- Architecture-First Approach: Design the application structure using Next.js conventions (pages/app router, API routes, middleware). Plan component hierarchy, state management, and data flow before implementation.
- Single Responsibility Principle: Each React component, custom hook, utility function, and API route should have one clear purpose. Separate business logic from presentation logic.
- Encapsulation: Use proper TypeScript access modifiers, private methods, and module boundaries. Expose only necessary props and interfaces from components and modules.
- DRY (Don't Repeat Yourself): Extract common functionality into custom hooks, utility functions, shared components, and reusable TypeScript types/interfaces.
- App Router Structure: Use the app directory structure with proper layout nesting, loading states, and error boundaries.
- Server vs Client Components: Explicitly mark client components with 'use client' and prefer server components for data fetching and static content.
- API Route Security: Implement proper HTTP method handling, request validation, and error responses in API routes.
- Performance Optimization: Utilize Next.js built-in optimizations (Image component, dynamic imports, static generation) and implement proper caching strategies.
- SEO and Metadata: Implement proper metadata API usage, structured data, and semantic HTML for better search engine optimization.
- Type Safety: Use strict TypeScript configuration with
strict: trueand additional strict flags (noImplicitReturns,noFallthroughCasesInSwitch). - NO
anyTYPES: NEVER useanytype. Always specify proper types. Useunknownfor truly unknown data, specific interfaces for objects, or union types for multiple possibilities. - Unused Variables: Prefix unused parameters with underscore (e.g.,
_event,_index) to indicate intentional non-use and avoid linting errors. - Interface Design: Define clear interfaces for props, API responses, and data models. Use generic types for reusable components.
- Type Guards: Implement proper runtime type checking using type guards or validation libraries like Zod for external data.
- Utility Types: Leverage TypeScript utility types (
Omit,Pick,Partial, etc.) for type transformations and avoid duplication.
- Component Design: Create small, focused components with clear prop interfaces. Use composition over inheritance.
- State Management: Choose appropriate state management (useState, useReducer, Zustand, Redux Toolkit) based on complexity and scope.
- Custom Hooks: Extract complex logic into custom hooks for reusability and testability.
- Error Boundaries: Implement error boundaries for graceful error handling in component trees.
- Accessibility: Follow WCAG guidelines with proper ARIA attributes, semantic HTML, and keyboard navigation support.
- Input Validation: Validate all user inputs using schema validation libraries (Zod, Yup) on both client and server sides.
- API Security: Implement CSRF protection, rate limiting, and proper authentication/authorization for API routes.
- XSS Prevention: Sanitize user-generated content and avoid dangerouslySetInnerHTML unless absolutely necessary.
- Environment Variables: Use Next.js environment variable conventions (
NEXT_PUBLIC_for client-side, secure server-only variables). - Content Security Policy: Implement CSP headers through next.config.js or middleware for additional security.
- Dependency Security: Regular dependency updates, use of
npm audit, and careful evaluation of third-party packages.
- Bundle Optimization: Use dynamic imports for code splitting, optimize bundle size with proper tree shaking.
- Image Optimization: Always use Next.js Image component with proper sizing, lazy loading, and format optimization.
- Caching Strategies: Implement appropriate caching with Next.js cache functions, SWR/React Query for client-side caching.
- Core Web Vitals: Monitor and optimize for LCP, FID, CLS, and other performance metrics.
- Testing Stack: Use Jest with React Testing Library for unit/integration tests, Playwright or Cypress for E2E tests.
- Component Testing: Test component behavior, user interactions, and accessibility features.
- API Testing: Test API routes with proper mocking and error scenarios.
- Type Testing: Use TypeScript compiler tests and tools like
tsdfor type-level testing.
- Linting and Formatting: Configure ESLint with Next.js rules, Prettier, and TypeScript-specific linting rules.
- Git Hooks: Implement pre-commit hooks for linting, type checking, and testing using Husky or similar tools.
- Code Review: Review for TypeScript type safety, React patterns, Next.js best practices, and security considerations.
- Follow Next.js and React conventions for file naming (kebab-case for files, PascalCase for components)
- Use ESLint rules:
@next/eslint-plugin-next,@typescript-eslint/recommended - Implement proper TypeScript path mapping in
tsconfig.jsonfor clean imports - Use Next.js built-in features (middleware, route handlers) over custom solutions
- Implement proper loading states and error handling for async operations
- Consider accessibility from the start with proper semantic HTML and ARIA attributes
- Implement analytics and monitoring (Web Vitals, error tracking)
- Use Next.js built-in performance metrics and bundle analysis
- Regular lighthouse audits and performance testing
Remember: These guidelines should enhance development velocity while maintaining code quality. Leverage TypeScript's type system and Next.js optimizations to build robust, scalable applications.
- Jest: Configured with Next.js integration
- React Testing Library: For component testing
- jsdom: Test environment for DOM testing
- Setup:
jest.setup.jswith testing-library/jest-dom - Coverage: Collects from
src/**/*.{ts,tsx}excluding type definitions - Path mapping: Supports
@/*imports in tests
- Playwright: E2E testing with WCAG accessibility validation using axe-core
- Test Requirements: Minimum 16 articles for pagination tests (15 items/page = 2 pages)
- Configuration:
playwright.config.jswith automatic dev server startup - CI Integration: Runs in GitHub Actions
quality-gatesjob - Commands:
npm run test:a11y- Run accessibility testsnpm run test:playwright- Run all Playwright testsnpm run verify-test-data- Verify sufficient articles exist for testing
- Test Data: See
tests/README.mdfor detailed requirements and best practices - Reports: HTML reports uploaded as artifacts in CI, viewable with
npx playwright show-report
- SITE_URL: Public origin for sitemap/RSS (validated with Zod)
- NEXT_PUBLIC_BASE_PATH: Handled automatically by CI for staging/production
- Validation: Runtime environment validation using
src/lib/env.ts - Defaults: Falls back to
http://localhost:3000in development
This project has a knowledge graph at graphify-out/ with god nodes, community structure, and cross-file relationships.
Rules:
- For codebase questions, first run
graphify query "<question>"when graphify-out/graph.json exists. Usegraphify path "<A>" "<B>"for relationships andgraphify explain "<concept>"for focused concepts. These return a scoped subgraph, usually much smaller than GRAPH_REPORT.md or raw grep output. - If graphify-out/wiki/index.md exists, use it for broad navigation instead of raw source browsing.
- Read graphify-out/GRAPH_REPORT.md only for broad architecture review or when query/path/explain do not surface enough context.
Update cadence (code only):
- The graph tracks code only (
src/**,scripts/**, config.ts/.js). Never rebuild it for content changes —content/articles/*.mdx, docs, or images do not trigger an update. - A git post-commit hook rebuilds the graph automatically in the background after every commit that touches code files (AST-only, no LLM cost). Committing is the primary update mechanism — do not run a manual update after committing.
- In-session, run
graphify update .manually only when both are true: (a) you changed code files that are still uncommitted, and (b) you are about to query the graph about that changed code. Do not run it after every edit.