Professional law firm website specializing in estate planning, built with Next.js 15 and React 19, deployed on Cloudflare Workers.
The site is deployed on Cloudflare Workers with automatic build and deployment on every push.
This is the official website for Anna M. Schneider Law, a law firm specializing in estate planning, living trusts, and wills. The site is built with modern web technologies to provide a fast, accessible, and user-friendly experience for clients seeking estate planning guidance.
- Framework: Next.js 15.3 with React 19
- Language: TypeScript 5
- Styling: Tailwind CSS v4 with custom CSS variables for theming
- Animation: Framer Motion for smooth transitions
- Icons: Lucide React for consistent iconography
- Email: Resend with React Email components
- Notifications: react-hot-toast for user feedback
- Deployment: Cloudflare Workers via OpenNext with automatic deployment
- Runtime: Node.js 22
- Package Manager: Yarn 4 (Berry) for fast, reliable dependency management
- Code Quality: ESLint with Next.js config, Stylelint for CSS linting, Prettier for formatting, lint-staged for pre-commit checks, Husky for git hooks, custom lint script with progress indicators
- Commit Standards: Commitlint for enforcing Conventional Commits specification
The website includes the following pages:
- Home (
/) - Hero section, key features, services overview, and call-to-action - About (
/about) - Attorney profile, philosophy, experience, and client reviews from Yelp - Services (
/services) - Detailed information about legal services offered - FAQ (
/faq) - Frequently asked questions about estate planning, living trusts, and wills - Contact (
/contact) - Contact form with email integration, office information, and map
This project requires:
- Node.js 22 or higher
- Yarn 4 (automatically managed via
.yarnrc.yml)
- Responsive Design - Mobile-first approach with seamless desktop experience
- Component-Based Architecture - Reusable React components for maintainability
- Type Safety - Full TypeScript implementation
- Custom Design System - CSS variables for consistent theming and easy customization
- Dark Mode - Full dark mode support with theme persistence and system preference detection
- Performance Optimized - Static generation and edge deployment for fast load times
- SEO Optimized - Page-specific metadata, Open Graph images, sitemap, robots.txt, and Schema.org structured data
- Accessibility - WCAG AA compliant with skip links, keyboard navigation, ARIA labels, and focus indicators
- Smooth Animations - Framer Motion for enhanced user experience
- Modern Icons - Lucide React icon library
- Contact Form - Integrated contact form with Resend email delivery and React Email templates
- User Notifications - Toast notifications for form submissions and user feedback
- Yelp Reviews Integration - Automatically displays latest client reviews from Yelp
- Interactive Maps - Office location map integration
- FAQ Section - Comprehensive answers to common estate planning questions
- Error Handling - Custom 404 page, error boundaries, and loading states
- Code Quality Tools - Pre-commit hooks with ESLint, Prettier, and automated testing
- Conventional Commits - Enforced commit message format for better version control and changelogs
- Comprehensive Testing - Unit tests with Vitest and E2E tests with Playwright
- Automatic Deployment - Cloudflare Workers automatically builds and deploys on every push
This project uses Dependabot to automatically keep dependencies up to date. Configuration is in .github/dependabot.yml.
Update Schedule:
- Monthly updates on Mondays at 9:00 AM PST
- Covers both npm packages and GitHub Actions
Dependency Groups: Dependabot groups related packages together to reduce PR noise:
- React - React and related packages
- Next.js - Next.js and framework packages
- Testing - Testing libraries (Vitest, Playwright, Testing Library)
- Linting - ESLint, Prettier, TypeScript, and related plugins
- Styling - Tailwind CSS and PostCSS
- Email - Resend and React Email packages
- Dev Dependencies - All development dependencies
Pull Request Features:
- Automatic PR creation with conventional commit messages (
chore:orci:) - Labels applied:
dependencies,automated,github-actions - Assigned reviewers configured
- Automatic rebase when PRs become outdated
- Maximum 5 open PRs for npm, 3 for GitHub Actions
This ensures the project stays secure and up-to-date with minimal manual intervention.
This project uses semantic-release to automatically manage versioning, generate changelogs, and create GitHub releases based on commit messages.
When code is merged to the main branch, semantic-release:
- Analyzes commits - Reviews commit messages since the last release
- Determines version - Calculates the next version based on commit types
- Updates files - Bumps version in
package.jsonand updatesdocs/CHANGELOG.md - Creates release - Generates GitHub release with release notes
- Commits changes - Pushes version updates back to the repository
The version bump is determined by your commit message type:
| Commit Type | Version Bump | Example |
|---|---|---|
feat: |
Minor (0.1.0 → 0.2.0) | feat: add user authentication |
fix: |
Patch (0.1.0 → 0.1.1) | fix: resolve mobile menu bug |
perf: |
Patch (0.1.0 → 0.1.1) | perf: optimize image loading |
feat!: or BREAKING CHANGE: |
Major (0.1.0 → 1.0.0) | feat!: redesign API |
docs:, style:, refactor:, test:, build:, ci:, chore: |
No release | Documentation and other changes |
- GitHub Releases: https://github.com/CampAsAChamp/amsfirm/releases
- Changelog:
docs/CHANGELOG.md- Automatically generated and maintained
Use Conventional Commits format to ensure proper versioning:
# Creates a minor release (0.1.0 → 0.2.0)
git commit -m "feat: add dark mode toggle"
# Creates a patch release (0.1.0 → 0.1.1)
git commit -m "fix: resolve navigation focus trap"
# No release created
git commit -m "docs: update README with new examples"
# Creates a major release (0.1.0 → 1.0.0)
git commit -m "feat!: redesign navigation API
BREAKING CHANGE: Navigation component now requires theme prop."See the Commit Message Guide for detailed information and examples.
- Workflow:
.github/workflows/release.yml- Runs on push to main - Configuration:
.releaserc.js- Semantic release settings - Changelog:
docs/CHANGELOG.md- Automatically generated
No secrets required - The GitHub Actions workflow uses the automatically provided GITHUB_TOKEN.
This project uses GitHub Actions for continuous integration and automated releases. The pipeline consists of two workflows that work together to ensure code quality and automate versioning.
Runs automatically on:
- Every push to
mainbranch - Every pull request to
mainbranch
Steps:
- Install dependencies - Uses Yarn with caching for faster builds
- Run linters - Executes comprehensive linting (ESLint, Stylelint, TypeScript, Prettier)
- Run unit tests - Runs Vitest unit tests
- Build - Creates Next.js production build to verify buildability
Status: Required check - PRs cannot be merged if tests fail.
Runs automatically only after the test workflow succeeds on the main branch.
Trigger: workflow_run event - waits for test workflow completion with success status
Steps:
- Runs semantic-release - Analyzes commits and determines next version
- Updates files - Bumps version in
package.jsonand updatesdocs/CHANGELOG.md - Creates release - Generates GitHub release with automated release notes
- Commits changes - Pushes version updates back to repository with
[skip ci]tag
This ensures all releases are tested and validated before being published.
The two-workflow approach provides several benefits:
- Quality Assurance - No releases happen unless all tests pass
- Fast Feedback - Test results appear immediately on PRs
- Automatic Versioning - Releases happen automatically when code is merged to
main - No Redundant Testing - Release workflow only runs after successful tests
- Clean Commit History - Release commits are tagged with
[skip ci]to prevent recursive workflows
- Test Workflow:
.github/workflows/test.yml - Release Workflow:
.github/workflows/release.yml - Semantic Release Config:
.releaserc.js
If you need to push changes without triggering the workflows, include [skip ci] in your commit message:
git commit -m "docs: update README [skip ci]"This is useful for documentation-only changes that don't require testing. However, semantic-release automatically adds [skip ci] to its release commits to prevent recursive workflows.
First, install dependencies:
yarn installThen run the development server:
yarn devOpen http://localhost:3000 with your browser to see the result.
The page auto-updates as you edit files. Start by modifying src/app/page.tsx for the home page.
Note: This project uses Yarn 4 (Berry). The correct version is automatically used via the
.yarnrc.ymlconfiguration file.
All scripts are defined in package.json and run with Yarn:
yarn dev- Start development server with hot reloadyarn build- Build Next.js production bundle (for local testing/verification)yarn start- Start production server locallyyarn lint- Run comprehensive linting (ESLint, Stylelint, TypeScript) with progress indicatorsyarn lint:fix- Run ESLint and Stylelint with auto-fix, plus type checkingyarn lint:eslint- Run only ESLint checksyarn lint:css- Run Stylelint on CSS filesyarn lint:css:fix- Auto-fix CSS linting issuesyarn lint:types- Run TypeScript type checking onlyyarn format- Format all files with Prettieryarn format:check- Check formatting without changesyarn check- Run full type checking and build validationyarn preview- Preview OpenNext build locallyyarn deploy- Build and deploy to Cloudflare Workers (includes build step)yarn cf-typegen- Generate TypeScript types for Cloudflare environmentyarn test- Run Vitest unit testsyarn test:watch- Run tests in watch modeyarn test:ui- Run tests with interactive UIyarn test:coverage- Generate coverage reportyarn test:e2e- Run Playwright end-to-end testsyarn test:e2e:ui- Run E2E tests with UIyarn test:e2e:debug- Debug E2E testsyarn test:e2e:animations- Run animation-specific E2E testsyarn test:e2e:visual- Run visual regression tests with screenshotsyarn test:e2e:visual:update- Update visual regression baseline snapshotsyarn test:lighthouse- Run Lighthouse performance audits (desktop)yarn test:lighthouse:desktop- Run Lighthouse audits for desktop viewportyarn test:lighthouse:mobile- Run Lighthouse audits for mobile viewportyarn test:lighthouse:both- Run Lighthouse audits for both desktop and mobileyarn test:all- Run all tests (unit + lighthouse + e2e)yarn prepare- Setup Husky git hooks
src/
├── app/
│ ├── (pages)/ # Route pages
│ │ ├── about/ # About page and components
│ │ ├── contact/ # Contact page and form
│ │ ├── faq/ # FAQ page and components
│ │ └── services/ # Services page and components
│ ├── api/ # API routes
│ │ └── contact/ # Contact form email endpoint
│ ├── components/ # Reusable UI components
│ │ ├── common/ # Common utilities (AddressDisplay, CopyButton, cards)
│ │ ├── contact/ # Contact-related (email templates, forms)
│ │ ├── hero/ # Hero section
│ │ ├── layout/ # Navigation, Footer, Banners
│ │ └── sections/ # Section components (CallToAction, SectionHeader)
│ ├── data/ # Site data and configuration (exported via barrel)
│ └── globals.css # Global styles and CSS variables
├── types/ # TypeScript type definitions
└── utils/ # Utility functions
This project includes comprehensive testing with three types of tests:
- Unit Tests - Test individual components and functions with Vitest
- E2E Tests - Test user interactions and workflows with Playwright
- Lighthouse Audits - Test performance, accessibility, best practices, and SEO
See the Testing Guide for detailed information on unit and E2E tests.
Lighthouse CI tests are configured to ensure the site meets high standards for performance, accessibility, best practices, and SEO.
# Test desktop viewport only (fastest)
yarn test:lighthouse:desktop
# Test mobile viewport only
yarn test:lighthouse:mobile
# Test both desktop and mobile (recommended)
yarn test:lighthouse:bothThe tests will:
- Build your Next.js site for production
- Start a local production server
- Run Lighthouse audits
- Display detailed scores and diagnostics
- Save reports to
test_results/lighthouse/
By default, local Lighthouse tests work without any configuration. However, if you want to upload reports to temporary public storage (like in CI), you can set up the LHCI GitHub token.
Setup (Optional):
- Get a Lighthouse CI token from Lighthouse CI
- Add it to your
.env.localfile (copy from.env.exampleif you haven't already):
# Optional: Upload Lighthouse reports to temporary public storage
LHCI_GITHUB_APP_TOKEN=your_token_here- Run tests as normal - the script automatically loads
.env.localif it exists
Note: This is completely optional for local development. Reports are always saved locally to test_results/lighthouse/ whether or not you have the token configured.
Lighthouse audits measure four key categories:
- Performance (≥85%) - Page load speed, Core Web Vitals (FCP, LCP, TBT, CLS, Speed Index)
- Accessibility (≥90%) - WCAG compliance, ARIA labels, keyboard navigation, color contrast
- Best Practices (≥90%) - Security, modern web standards, console errors
- SEO (≥90%) - Meta tags, structured data, mobile-friendliness, crawlability
After tests complete, you'll see:
-
Category Scores - Overall scores for each category with color-coded indicators:
- 🟢 Green (90-100): Excellent
- 🟡 Yellow (50-89): Needs improvement
- 🔴 Red (0-49): Poor
-
Core Web Vitals - Key performance metrics:
- First Contentful Paint (FCP) - How quickly content appears
- Largest Contentful Paint (LCP) - When main content loads
- Total Blocking Time (TBT) - How long the page is unresponsive
- Cumulative Layout Shift (CLS) - Visual stability during load
- Speed Index - How quickly content is visually displayed
-
Performance Opportunities - Specific recommendations to improve scores with estimated time savings
-
Full Report Link - Link to detailed HTML report with all audit details
Lighthouse tests run automatically in GitHub Actions:
- Triggered on every push and pull request to
mainbranch - Tests desktop configuration for consistent, fast CI execution
- Results appear in the Actions tab with detailed scores
- Reports uploaded to temporary public storage for 7 days
- Required check - PRs cannot be merged if Lighthouse tests fail
The Lighthouse job runs after unit tests pass, ensuring quality gates are enforced before code is merged.
Setting Up GitHub Secret (For CI/CD):
To enable report uploads in CI/CD, set the LHCI_GITHUB_APP_TOKEN secret:
- Go to Lighthouse CI GitHub App and install it for your repository
- The app will provide you with a token
- Add the token as a GitHub secret:
- Go to your repository → Settings → Secrets and variables → Actions
- Click "New repository secret"
- Name:
LHCI_GITHUB_APP_TOKEN - Value: Your token from step 2
- Click "Add secret"
Once configured, Lighthouse reports will be automatically uploaded and linked in CI/CD runs.
Configuration files define test parameters:
.lighthouserc.desktop.json- Desktop viewport with preset configuration.lighthouserc.mobile.json- Mobile viewport with 4G throttling simulation
Scripts:
scripts/run-lighthouse.sh- Orchestrates test execution and result collectionscripts/print-lighthouse-scores.mjs- Parses and displays test results with diagnostics
Tests fail with low performance scores:
- Performance can vary based on your machine's current load
- Run tests when your computer isn't under heavy load
- Mobile tests typically score lower than desktop (this is expected)
- Review performance opportunities for specific improvements
Server won't start:
- Ensure no other process is using port 3000
- Check that
yarn buildcompletes successfully - Verify you have Node.js 22 or higher
Tests timeout:
- Increase
startServerReadyTimeoutin.lighthouserc.*.jsonif your machine is slow - Default is 10 seconds, which should be sufficient for most cases
The project includes several configuration files that control different aspects of the build, deployment, and development workflow:
| File | Purpose |
|---|---|
vitest.config.ts |
Vitest unit test configuration (jsdom environment, coverage settings) |
playwright.config.ts |
Playwright E2E test configuration (browser targets, reporters) |
.stylelintrc.json |
Stylelint rules for CSS linting (alphabetical properties, Tailwind support) |
commitlint.config.mjs |
Commit message format enforcement (Conventional Commits) |
eslint.config.mjs |
ESLint rules and Next.js configuration |
postcss.config.mjs |
PostCSS with Tailwind CSS v4 |
open-next.config.ts |
OpenNext adapter configuration for Cloudflare Workers |
wrangler.jsonc |
Cloudflare Workers deployment configuration |
.cursorrules |
Project-specific coding standards and conventions |
The contact form uses Resend for email delivery and React Email components for beautiful, responsive email templates. Here's how to set it up:
- Go to resend.com
- Sign up for a free account (100 emails/day, 3,000 emails/month)
- Verify your email address
- Go to API Keys
- Click "Create API Key"
- Name it something like "AMS Law Website"
- Copy the API key (starts with
re_)
For Local Development:
Copy .env.example to .env.local and fill in your values:
cp .env.example .env.localThen edit .env.local:
# Resend API Configuration
RESEND_API_KEY=re_your_api_key_here
# Email address where contact form submissions will be sent
[email protected]For Production (Cloudflare Workers):
- Update
CONTACT_EMAILinwrangler.jsonc:
- Set
RESEND_API_KEYas a secret using Wrangler CLI:
yarn wrangler secret put RESEND_API_KEYWhen prompted, paste your Resend API key. This stores it securely in Cloudflare and persists across all deployments.
For the free tier, you can use Resend's default sending domain ([email protected]), but emails will be more professional from your own domain.
To use your own domain:
- Go to Domains in Resend dashboard
- Click "Add Domain"
- Enter your domain (e.g.,
schneiderlaw.com) - Add the DNS records shown to your domain provider
- Wait for verification (usually 5-10 minutes)
- Update the API route to use your domain:
In src/app/api/contact/route.ts, change:
from: 'AMS Law Contact Form <[email protected]>',to:
from: 'AMS Law Contact Form <[email protected]>',- Start your development server:
yarn dev - Navigate to the Contact page
- Fill out and submit the form
- Check your email!
"Failed to send email" error:
- Check that your
.env.localfile exists and has the correct API key - Restart your dev server after creating/updating
.env.local - Verify your API key is active in the Resend dashboard
Not receiving emails:
- Check your spam folder
- Verify the
CONTACT_EMAILis correct (in.env.localfor local,wrangler.jsoncfor production) - Check the Resend dashboard Emails to see if they're being sent
- For production, verify you've set the
RESEND_API_KEYsecret usingyarn wrangler secret put RESEND_API_KEY
Environment Variables:
- ✅ Local: Use
.env.local(never commit this file) - ✅ Production: Set
CONTACT_EMAILinwrangler.jsoncandRESEND_API_KEYvia Wrangler CLI - Make sure you've verified your domain for better deliverability
Security Notes:
- Never commit your
.env.localfile to git - The API key is server-side only (Next.js API route)
- Users cannot see or access your API key from the browser
The About page displays client reviews from Yelp with star ratings and reviewer information. These are currently stored as static data for reliability and performance.
- Reviews are stored in
src/app/data/reviews.tsx - Displays with Yelp-style formatting (star ratings, reviewer names, dates)
- Includes link to view all reviews on Yelp
- Fast loading (no external API calls)
When you receive a new Yelp review:
- Go to your Yelp business page: https://www.yelp.com/biz/anna-m-schneider-torrance
- Find the new review and click "Share review" directly on the review
- Click "Copy Link" to get the review URL (it will include
?hrid=and tracking parameters) - Open
src/app/data/reviews.tsx - Add the new review to the
yelpReviewsarray:
{
id: "reviewer-name-year",
url: "https://www.yelp.com/biz/anna-m-schneider-torrance?hrid=xxxxx", // Use the URL from step 3
text: "The review text from Yelp",
rating: 5, // 1-5 stars
time_created: "2024-01-15T00:00:00Z", // ISO format
user: {
id: "reviewer-id",
profile_url: "https://www.yelp.com/user_details?userid=reviewer-id",
image_url: null, // or URL to profile image if available
name: "Reviewer Name",
},
}- Save the file and deploy
Tip: The ?hrid= parameter in the URL ensures the "Read more on Yelp" link goes directly to that specific review.
We use static reviews instead of the Yelp API because:
- ✅ Reliable: No API issues or rate limits
- ✅ Fast: Instant page loads, no external API calls
- ✅ Simple: No API keys or credentials needed
- ✅ Free: No API costs
- ✅ Maintained: Easy to update when you get new reviews
Since reviews don't change frequently, this approach provides the best user experience.
The site is deployed to Cloudflare Workers with automatic build and deployment configured through Cloudflare's Git integration. Every push to the main branch automatically:
- Builds the Next.js application
- Generates the Cloudflare Workers bundle using OpenNext
- Deploys to production at amsfirm.com
You can also deploy manually using the following commands:
| Command | Action |
|---|---|
yarn build |
Build your Next.js production site |
yarn preview |
Preview OpenNext build locally |
yarn deploy |
Build and deploy to Cloudflare Workers |
yarn lint |
Run ESLint to check code quality |
yarn check |
Build and run TypeScript type checking |
Important: yarn deploy automatically runs the build process internally (via opennextjs-cloudflare build), so you don't need to run yarn build before deploying. The standalone yarn build command is useful for:
- Local verification of the Next.js build
- Type checking with
yarn check(which runsyarn build && tsc) - Testing the build without deploying
For Cloudflare deployment, just run yarn deploy - it handles everything in one command.
This project uses OpenNext to adapt Next.js for Cloudflare Workers. The configuration is in open-next.config.ts.
Current Setup:
- Uses default OpenNext settings optimized for Cloudflare Workers
- Automatic static asset handling
- Server-side rendering support on the edge
Optional Performance Enhancement:
You can enable R2 incremental cache for improved performance:
- Uncomment the R2 cache configuration in
open-next.config.ts - Import the R2 cache override:
import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache" - Add to config:
incrementalCache: r2IncrementalCache
See OpenNext Cloudflare Caching for more details.
The project uses Wrangler CLI for Cloudflare Workers management. Useful commands:
TypeScript Types:
yarn cf-typegenGenerates TypeScript types for Cloudflare environment variables defined in wrangler.jsonc.
Managing Secrets:
# Set a secret (encrypted)
yarn wrangler secret put SECRET_NAME
# List all secrets
yarn wrangler secret list
# Delete a secret
yarn wrangler secret delete SECRET_NAMEConfiguration in wrangler.jsonc:
vars- Public environment variables (e.g.,CONTACT_EMAIL)compatibility_date- Cloudflare Workers compatibility datecompatibility_flags- Node.js compatibility and other feature flagsobservability- Logging and monitoring configurationupload_source_maps- Enable source maps for better debugging
Environment variables are configured in wrangler.jsonc:
- Non-sensitive variables (like
CONTACT_EMAIL,NEXT_PUBLIC_SITE_URL): Set in thevarssection ofwrangler.jsonc - Secrets (like
RESEND_API_KEY): Set usingyarn wrangler secret put VARIABLE_NAME
Secrets set via Wrangler CLI are encrypted and stored securely in Cloudflare, persisting across all deployments.
Note: The NEXT_PUBLIC_SITE_URL variable is used for SEO features (sitemap, Open Graph images, structured data). Set it to your production domain (e.g., https://amsfirm.com).
This project uses a custom design system with CSS variables defined in src/app/globals.css:
- Color Variables - Consistent color palette using CSS custom properties
- Dark Mode Support - Automatic theme switching with CSS variables for light and dark modes
- Utility Classes - Pre-defined button styles, text colors, and backgrounds
- Responsive Breakpoints - Tailwind CSS breakpoints for responsive design
- Focus Indicators - WCAG-compliant focus styles for keyboard navigation
The site includes full dark mode support:
- Theme Toggle - Sun/moon icon button in navigation to switch themes
- Persistence - Theme preference saved in localStorage
- System Preference - Respects user's OS dark mode setting on first visit
- No Flash - Theme applied before page render to prevent flash of wrong theme
- Consistent Colors - Primary blue brand color maintained across both themes
To use dark mode in your components:
import { useTheme } from "@/app/components/common"
function MyComponent() {
const { theme, toggleTheme } = useTheme()
// theme is "light" or "dark"
}The project uses a comprehensive linting setup with a custom script for better developer experience:
Comprehensive Linting (yarn lint):
The yarn lint command runs a custom script (scripts/lint-with-progress.mjs) that executes three checks sequentially with visual progress indicators:
- ESLint - JavaScript/TypeScript code quality and Next.js best practices
- Stylelint - CSS formatting and Tailwind CSS compliance
- TypeScript - Type checking across the entire codebase
The script shows a spinner progress indicator while running each check and provides clear success/failure feedback.
Individual Linters:
For faster feedback during development, you can run individual linters:
yarn lint:eslint- Only ESLint checksyarn lint:css- Only Stylelint checksyarn lint:types- Only TypeScript type checkingyarn lint:fix- Auto-fix ESLint and Stylelint issues, then type check
Pre-commit Hooks:
Git hooks via Husky automatically run lint-staged on committed files:
- Auto-fixes ESLint and Stylelint issues
- Formats code with Prettier
- Only processes staged files for speed
- Configured in
package.jsonunderlint-staged
Stylelint Configuration:
CSS linting enforces:
- Alphabetical property ordering
- Tailwind CSS compatibility
- Hex color format consistency (long form)
- No named colors (except in functions)
- Custom rules for
globals.cssexceptions
See .stylelintrc.json for complete configuration.
- Always use CSS variables and utility classes for colors (never hardcode colors)
- Use absolute imports with
@/alias for all local files - Follow TypeScript strict mode for type safety
- Keep components focused and single-responsibility
- Ensure all interactive elements are keyboard accessible
- Add proper ARIA labels for screen readers
- Use Conventional Commits for all commit messages
See .cursorrules for complete coding standards and conventions.
All commits must follow the Conventional Commits specification. This is enforced automatically via git hooks.
Format:
<type>[optional scope]: <description>
Example:
feat: add contact form validation
fix(nav): resolve mobile menu focus trap
docs: update deployment instructionsSee the Commit Message Guide for detailed information and examples.
Additional documentation is available in the docs/ directory:
- Git Hooks Setup - Pre-commit and pre-push hooks for code quality
- Commit Message Guide - Quick reference for writing conventional commits
- Testing Guide - Comprehensive testing documentation for unit and E2E tests
The docs/reference/ directory contains detailed markdown documentation about legal services:
- Living Trusts - Comprehensive information about living trusts
- Wills - Information about wills and estate planning
These documents serve as content reference for the website and can be used for FAQ content or service descriptions.
- Next.js Documentation - Next.js features and API
- React Documentation - React 19 features and hooks
- Tailwind CSS v4 - Utility-first CSS framework
- React Email - Build and send emails with React components
- Resend Documentation - Email delivery API
- OpenNext Documentation - Learn about the deployment adapter
- Cloudflare Workers - Deployment platform
- TypeScript Handbook - TypeScript language reference