UXDL Docs

React + Vite

Create a Vite SPA, configure routing, and integrate with the API.

Use Vite for client-rendered React applications — internal tools, embeddable widgets, and lightweight SPAs that do not require SSR.

Create the project

bash
pnpm create vite web-app --template react-ts
cd web-app
pnpm install
pnpm add react-router-dom zustand @aws-amplify/auth
pnpm dev

Project structure

plaintext
src/
├── components/     # Shared UI components
├── features/       # Feature-specific modules
├── lib/            # API client, auth, utilities
├── stores/         # Zustand stores
├── routes/         # Route definitions
└── main.tsx

Environment variables

dotenv
VITE_API_URL=http://localhost:4000/api
VITE_COGNITO_USER_POOL_ID=us-east-1_xxxxx
VITE_COGNITO_CLIENT_ID=xxxxxxxx
VITE_COGNITO_DOMAIN=auth.company.com

API client

typescript
// src/lib/api.ts
const BASE = import.meta.env.VITE_API_URL;
 
export async function apiFetch(path: string, options: RequestInit = {}) {
  const token = await getAccessToken();
  const res = await fetch(`${BASE}${path}`, {
    ...options,
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${token}`,
      ...options.headers,
    },
  });
  if (!res.ok) throw new ApiError(res.status, await res.text());
  return res.json();
}

Routing with auth guards

typescript
// src/routes/index.tsx
import { createBrowserRouter } from 'react-router-dom';
import { ProtectedRoute } from './ProtectedRoute';
 
export const router = createBrowserRouter([
  { path: '/login', element: <LoginPage /> },
  {
    path: '/',
    element: <ProtectedRoute><AppLayout /></ProtectedRoute>,
    children: [
      { index: true, element: <Dashboard /> },
      { path: 'settings', element: <Settings /> },
    ],
  },
]);

Verify setup

bash
pnpm lint && pnpm typecheck && pnpm test && pnpm build
pnpm dev

Confirm login, API calls, and route guards before opening a PR.