aboutsummaryrefslogtreecommitdiffstatshomepage

React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some Oxlint rules.

Environment variables

Copy .env.example to .env and adjust the values:

VITE_ROUTER_MODE=hash
VITE_BASE_URL=/app/
Variable Default Description
VITE_ROUTER_MODE history history or hash; other values fail startup/build.
VITE_BASE_URL / Deployment pathname for assets and routing, such as /app/. Must start with a single /, without query strings, fragments, whitespace, or backslashes. A trailing / is added automatically.

With /app/, the About page is /app/about in history mode and /app/#/about in hash mode. History mode requires the host to serve /app/index.html for application paths under /app/. Hash mode does not require a server-side route fallback.

Shell environment variables override .env values:

VITE_ROUTER_MODE=hash VITE_BASE_URL=/app/ pnpm build

Vite also loads .env.local, .env.[mode], and .env.[mode].local. Mode-specific files override generic files; shell variables have highest priority. For example, pnpm build --mode staging loads .env.staging. Environment files are ignored by Git except for .env.example. Restart the development server after changing variables. Production values are embedded during the build; changing server environment variables requires rebuilding. Custom frontend variables use the VITE_ prefix and are read through import.meta.env. These values are public, so do not put secrets in them. See Vite environment variables.

Routing

Routing uses React Router Data Mode. src/route-config.ts is the single source for page paths, components, titles, icons, menu groups, and default expanded groups. It generates the page routes and menu data. src/router.tsx creates the router with createBrowserRouter or createHashRouter, and src/main.tsx renders it with RouterProvider. src/App.tsx configures the Spectrum Provider and renders the route Outlet inside BasicLayout. src/components/layout-basic.tsx owns the sidebar, top bar, collapse state, and content area, with styles in src/components/layout-basic.module.css. It accepts page content through children. src/components/sidebar-menu.tsx provides the shared menu list, and src/components/collapsed-navigation.tsx renders the same data in icon mode. The top bar reads the title from the matched route's metadata. On screens up to 640px wide, src/components/mobile-navigation.tsx opens it in a full-screen modal from the top bar. Selecting a page or closing the modal returns to the content.

  • /: the homepage in src/page-home.tsx.
  • /about: the about page in src/page-about.tsx.
  • /form: the Spectrum form showcase in src/page-form.tsx.
  • /ui-kit: the Spectrum component showcase in src/page-ui-kit.tsx.
  • Unmatched paths: the 404 page in src/page-not-found.tsx.

Place page components directly in src/ and name their files page-*.tsx. Place shared components and their styles in src/components/. Use colocated *.module.css files for page and component styles. Keep global theme variables, document styles, and resets in src/index.css. Shared menu icon styles live in src/components/menu-icon.module.css, and the basic page spacing is shared through src/page.module.css.

The top-right settings button opens src/components/global-settings.tsx with light and dark appearance options. src/theme.ts provides the shared theme context; App synchronizes it with Spectrum's Provider and the document theme. The initial theme uses the saved preference, or the system preference on first visit. Selections persist in local storage when it is available.

UI Kit

src/components/ui-kit/ contains lazily loaded examples of buttons, badges, status lights, alerts, progress indicators, dialogs, popovers, tooltips, toasts, breadcrumbs, tabs, accordions, removable tags, cards, and a sortable table with row selection. Examples respond to the global light/dark appearance setting.

Form showcase

src/components/form-examples/ contains lazily loaded examples of text, password, email, URL, telephone, search, multiline, number, checkbox, radio, switch, picker, combo box, select box, segmented control, toggle buttons, slider, range slider, date/time fields, date pickers, calendars, color controls, file selection, and drag and drop. Layout controls demonstrate sizes, label positions, and disabled states. Each field has its own named label/input grid. Side labels automatically fall back to top labels when the form container is narrower than 560px, and restore when sufficient space is available.

Submission uses native validation plus a custom username rule. The username admin demonstrates a local business validation error. A successful submission shows a data preview with the password masked; no data or files are uploaded. Reset remounts the examples to clear both native inputs and controlled widget state.

Add pages to routeConfig in src/route-config.ts with a unique id, title, absolute path, Component, and optional Icon. Use children for menu groups and defaultExpanded to control their initial expansion. Menu groups do not change page URLs. Set hidden: true to keep a route out of navigation, as with the 404 page. Desktop, collapsed, and mobile menus all use this configuration. When deploying in history mode, configure your host to serve index.html from the configured base directory for application URLs so direct visits and refreshes on nested routes work.

Currently, two official plugins are available:

React Compiler

The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see this documentation.

Expanding the Oxlint configuration

If you are developing a production application, we recommend enabling type-aware lint rules by installing oxlint-tsgolint and editing .oxlintrc.json:

{
  "$schema": "./node_modules/oxlint/configuration_schema.json",
  "plugins": ["react", "typescript", "oxc"],
  "options": {
    "typeAware": true
  },
  "rules": {
    "react/rules-of-hooks": "error",
    "react/only-export-components": ["warn", { "allowConstantExport": true }]
  }
}

See the Oxlint rules documentation for the full list of rules and categories.