A modern, accessibility-first React 19 application built with Vite 7 and TypeScript 5. This template enforces strict rules for accessibility (WCAG 2.2 AA), performance, and code quality.
๐ Fork-Friendly Setup: This template is designed to work out-of-the-box for forks! All advanced features (CodeQL, SonarCloud, GitHub Pages CI, JSDoc) are disabled by default and only run when you explicitly enable them. See .env.example for minimal setup instructions.
A compact, searchable wiki for quick project notes, operational runbooks, diagrams, and short HOWTOs.
Explore the full documentation, architecture, and deep technical notes for this project on DeepWiki:
โ ๏ธ Note for Forks: The SonarCloud badges above are for the original repository. If you're not using SonarCloud, you can safely remove these badges (lines 3-7).
dist/)See Feature Configuration for a canonical list of optional repository Actions variables (ENABLE_*) and detailed setup instructions for CodeQL, SonarCloud, GitHub Pages, and JSDoc.
By default, this repository treats CodeQL scans as opt-out to avoid heavy analysis running automatically on forks and CI. Use one of these methods to run CodeQL:
run_codeql input is true.ENABLE_CODEQL with value true under Settings โ Secrets and variables โ Actions โ Variables (or Secrets). When set to true, scheduled/push/PR runs will be allowed.This matches the workflow gating in .github/workflows/codeql.yml.
This template uses SonarCloud for continuous code quality and security analysis. Configuration is driven by environment variables so forks can set up their own SonarCloud projects without editing source files.
Setup Requirements (for your fork or repo):
my-org)my-org_modern-react-template)SONAR_TOKEN to your GitHub repository secrets (Project Settings โ Security โ Tokens in SonarCloud).SONAR_ORGANIZATION โ your SonarCloud organization keySONAR_PROJECT_KEY โ your SonarCloud project keySONAR_TOKEN โ the token from SonarCloudENABLE_SONARCLOUD with value true to enable SonarCloud analysis. Set it to false (or remove it) to skip the SonarCloud job.The sonar-project.properties file reads SONAR_ORGANIZATION and SONAR_PROJECT_KEY at analysis time, so no changes are required in the file when you fork this template.
View your project's quality metrics on the SonarCloud dashboard when analysis is enabled.
The template automatically deploys four entry points to GitHub Pages on every push to main:
https://asudbury.github.io/modern-react-template/https://asudbury.github.io/modern-react-template/apphttps://asudbury.github.io/modern-react-template/docsSetup Requirements:
main branch to trigger deploymentImportant: Deployment only happens from the main branch. The workflow automatically configures proper base paths for asset loading.
This template uses a global error boundary to catch unexpected errors anywhere in the React component tree and display a user-friendly fallback UI instead of a blank screen or crash.
react-error-boundarysrc/main.tsx wrapping the entire appsrc/components/ErrorFallback/ErrorFallback.tsxPrerequisites:
# Install dependencies
npm install
# Start development server
npm run dev
Visit http://localhost:5173 to see your application.
๐ด Forked this repo? See QUICKSTART.md for fork-specific setup instructions. All optional features (SonarCloud, GitHub Pages, etc.) are disabled by default and won't interfere with your fork.
This template uses TanStack Router for type-safe client-side routing. The router is configured in src/router.tsx and integrated into the app via App.tsx.
The template includes a Navigation component that uses TanStack Router's Link component for type-safe navigation:
import { Link } from '@tanstack/react-router';
<Link to="/" activeProps={{ className: 'active' }}>
Home
</Link>
/ - Home page (HomePage component)* (any unmatched path) โ 404 Not Found page (NotFoundPage component)This template includes a fully accessible, customizable 404 Not Found page for unmatched routes. The 404 page:
Customizing the 404 page:
src/pages/NotFoundPage/NotFoundPage.tsx to change the message, add illustrations, or update the layoutsrc/router.tsx with path: '*'Demo: On the home page, click the "Demo 404 Not Found page" link to preview the 404 page in the app.
To add a new route, update src/router.tsx:
import { createRoute } from '@tanstack/react-router';
import { YourComponent } from './pages/YourComponent';
const yourRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/your-path',
component: YourComponent,
});
// Add to routeTree
const routeTree = rootRoute.addChildren([
indexRoute,
yourRoute
]);
TanStack Router provides full TypeScript autocomplete and type checking for routes:
import { Link, useNavigate } from '@tanstack/react-router';
// Link component with autocomplete
// Programmatic navigation
const navigate = useNavigate();
navigate({ to: '/' });
For more details, see the TanStack Router documentation.
npm run dev - Start development servernpm run build - Build for production (no GitHub Pages side effects)npm run preview - Preview production buildnpm run lint - Run ESLintnpm run lint:fix - Fix ESLint issuesnpm run prettier - Format code with Prettiernpm run knip - Analyze for unused files, exports, and dependencies (see below)git commitThis template uses Knip to detect unused files, exports, and dependencies:
npm run knip locally to see a report of unused code and dependenciesExample:
npm run knip
# or in CI, download the knip-report artifact for details
See knip.toml for configuration details.
npm run test - Run unit tests in watch modenpm run test:unit - Run unit testsnpm run test:coverage - Run unit tests with coverage reportnpm run test:ui - Run tests with UInpm run test:e2e - Run E2E tests with Playwrightnpm run docs - Generate both markdown and HTML documentationnpm run docs:md - Generate markdown documentation in docs/npm run docs:html - Generate HTML documentation in docs-html/npm run update:gh-page-details - Inject package.json version into a copy of public/gh-pages-index.html and write it to dist/gh-pages-index.html (used for GitHub Pages landing page)npm run build:gh-pages - Build the app and, when ENABLE_GH_PAGES=true, generate GitHub Pages artifacts (including dist/gh-pages-index.html)npm run cleanup - Interactive script to remove optional features and customize the template to your needs๐งน Cleanup Tool: Use
npm run cleanupto interactively remove features you don't need (Playwright, commitlint, SonarCloud, TypeDoc, GitHub Pages, etc.). This helps you start with a minimal setup tailored to your project. See scripts/README.md for details.
modern-react-template/
โโโ .github/
โ โโโ workflows/
โ โ โโโ ci.yml # CI/CD pipeline
โ โ โโโ codeql.yml # CodeQL security scanning (opt-in)
โ โ โโโ sonarcloud.yml # SonarCloud analysis (opt-in)
โ โ โโโ pages.yml # GitHub Pages deployment (opt-in)
โ โโโ copilot-instructions.md # Copilot coding guidelines
โโโ .husky/
โ โโโ pre-commit # Pre-commit hooks
โ โโโ pre-commit-secrets # Pre-commit secrets hooks
โโโ docs/ # Generated markdown docs (TypeDoc)
โโโ docs-html/ # Generated HTML docs (TypeDoc)
โโโ knip.toml # Knip configuration (unused code analysis)
โโโ playwright/ # UI tests
โโโ src/
โ โโโ components/ # Reusable UI components and samples
โ โ โโโ Button/ # Button component (+ tests, stories, index)
โ โ โโโ Navigation/ # Navigation bar
โ โ โโโ ErrorFallback/ # Global error fallback for error boundary
โ โโโ pages/ # Route/page components
โ โโโ queries/ # Data fetching/mutations (TanStack Query)
โ โโโ schemas/ # Zod schemas and types
โ โโโ test/ # Test setup/mocks
โ โโโ App.tsx # Root app component
โ โโโ main.tsx # Entry point (includes error boundary)
โ โโโ router.tsx # Router config
โ โโโ index.css # Global styles
โโโ .env.example # Environment variables template
โโโ .gitignore # Git ignore rules
โโโ .gitleaks.toml # Secret scanning config (Gitleaks)
โโโ .gitleaksignore # Secret scanning ignore rules
โโโ .prettierrc # Prettier configuration
โโโ eslint.config.js # ESLint configuration
โโโ package.json # Dependencies and scripts
โโโ playwright.config.ts # Playwright configuration
โโโ sonar-project.properties # SonarCloud configuration
โโโ tsconfig.json # TypeScript configuration
โโโ typedoc.json # TypeDoc markdown config
โโโ typedoc.html.json # TypeDoc HTML config
โโโ vite.config.ts # Vite configuration
โโโ vitest.config.ts # Vitest configuration
This template generates comprehensive documentation in multiple formats:
docs/)The docs/ directory contains auto-generated markdown documentation from TypeDoc. This is committed to the repository and provides developer-friendly API documentation.
npm run docs:md
HTML documentation is automatically generated and deployed to GitHub Pages:
This template ships with several concrete samples you can use as references:
src/pages/HomePage/HomePage.tsx demonstrates accessible page structure and headings.src/components/Button/ includes the button implementation and unit testssrc/queries/fetch.ts and src/queries/mutate.ts show how to use TanStack Query with Zod validation.playwright/homepage.spec.ts is a full Playwright + axe-core example for the home page.docs/ and docs-html/ contain TypeDoc output you can browse as living samples of the project APIs.Husky enforces code quality on every commit:
If any of these checks fails, the commit is blocked and the corresponding
command's error output is shown in your terminal (for example ESLint errors
or failing tests). Fix the reported issues and re-run git commit.
Additionally, a Husky commit-msg hook runs commitlint to enforce
Conventional Commits for commit
messages. Example:
feat: add a new component
fix: handle invalid user IDs in updateUser
chore: configure commitlint for commit messages
Optional build steps for GitHub Pages are controlled via repository-level Actions variables, not committed to the repo. Configure them at:
https://github.com/asudbury/modern-react-template/settings/variables/actions
This template supports accessible theming with light and dark modes, powered by design tokens and utility classes in src/index.css.
ThemeToggleButton component)src/index.cssFor more, see the ThemeToggleButton for reference.
useCallback or named functionsAll public APIs (exported functions, components, types) should optionally include JSDoc comments:
/**
* Button Component
*
* An accessible button component following WCAG 2.2 AA guidelines.
*
* @example
* ```tsx
* <Button variant="primary" onClick={handleClick}>
* Click me
* </Button>
* ```
*/
export function Button({ variant = 'primary', ...props }: ButtonProps) {
// Implementation
}
getByRole, getByLabelText)userEvent.setup(), never fireEvent
## Environment Variables
Create a `.env` file based on `.env.example`:
```bash
cp .env.example .env
All environment variables must be prefixed with VITE_ to be exposed to the client.
For local tooling and CI toggles, additional variables are defined in
.env.example (not exposed to the client), including:
SONAR_ORGANIZATION, SONAR_PROJECT_KEY, SONAR_TOKEN โ SonarCloud configENABLE_SONARCLOUD โ enable/disable SonarCloud in CISKIP_COMMITLINT โ set to true to temporarily skip commit message
linting enforced by Husky + commitlintThe CI pipeline runs on every push and pull request:
This repository's GitHub Actions workflows cache npm and build artifacts to speed CI runs. Common ways to inspect and control caches:
Cache restored from key:
(cache hit) or Cache not found for input key: (cache miss).package-lock.json (recommended) so
lockfile-based cache keys change, or temporarily change the workflow
cache key (not recommended long-term).${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}${{ runner.os }}-vite-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/vite.config.ts') }}If you want help verifying a cache hit/miss on a recent Actions run, tell me which run and I can point to the relevant log lines.
Husky runs the following checks on every commit:
If any check fails, the commit is blocked.
This repository includes local and CI secret scanning using gitleaks.
package.json):# Full repo scan
npm run secrets:scan
# Scan only staged changes (good for pre-commit hooks)
npm run secrets:scan-staged
# Create/update baseline report
npm run secrets:baseline
npm run secrets:scan-staged to your Husky pre-commit hook (or run it manually before committing). CI still runs a full scan via the secret-scan job.This template is designed to be extensible. See EXTENSIONS.md for comprehensive guides on:
MIT