- React with TypeScript
- Vite for dev server and build
- Tailwind CSS for styling
- shadcn/ui (new-york style) for UI components — do NOT hand-edit
src/components/ui/files - Magic UI for animations and effects
- wouter with browser routing (
base: "/page-agent") - lucide-react for icons
ALWAYS prefer shadcn/ui components over custom implementations.
Before creating any UI component, check if shadcn already provides it:
# IMPORTANT: Run from packages/website/, NOT from repo root
cd packages/website
# Add a new shadcn component
npx shadcn@latest add <component-name>
# Add a Magic UI component
npx shadcn@latest add "@magicui/<component-name>"Available shadcn components: https://ui.shadcn.com/docs/components Available Magic UI components: https://magicui.design/docs/components
Located in src/components/ui/:
From shadcn/ui:
alert,badge,button,separator,sonner,switch,tooltip
From Magic UI:
animated-gradient-text,animated-shiny-text,aurora-texthyper-text,magic-card,neon-gradient-card,particlessparkles-text,text-animate,typing-animation
Custom:
highlighter,kbd,spinner
- Prefer Tailwind classes over custom CSS
- Support dark mode via
dark:classes - Use CSS variables from
src/index.cssfor theme colors
src/
├── pages/
│ ├── home/
│ │ ├── index.tsx # Homepage
│ │ └── ...Section.tsx
│ └── docs/
│ ├── index.tsx # Docs route switch
│ ├── Layout.tsx # Sidebar navigation
│ └── [section]/[topic]/page.tsx
├── components/
│ ├── ui/ # shadcn/ui + Magic UI (DO NOT hand-edit)
│ ├── Heading.tsx # Anchor heading for doc pages
│ ├── Header.tsx # Site header
│ └── Footer.tsx # Site footer
├── i18n/ # Internationalization
├── router.tsx # Root layout + routing
└── main.tsx # App entry
Uses wouter browser routing with base path for GitHub Pages deployment at https://alibaba.github.io/page-agent/.
// main.tsx
<Router base="/page-agent">
<PagesRouter />
</Router>Key rules:
- Header and Footer live in
router.tsxoutside<Switch>, so they always see the root router context (base="/page-agent") - Docs pages are nested via
<Route path="/docs" nest>, which creates a child context (base="/page-agent/docs") - Inside the docs nest, Link hrefs are relative to
/docs(e.g.href="/features/models", NOThref="/docs/features/models") - Never use
~prefix in Link hrefs — it bypasses the base path entirely - Doc page headings use
<Heading id="slug" level={2}>for anchor links
Instead of 404.html redirects, the build copies index.html into every route directory. Add new routes to the SPA_ROUTES array in vite.config.js.
- Create
src/pages/docs/<section>/<slug>/page.tsx - Add route in
src/pages/docs/index.tsx - Add navigation item in
src/pages/docs/Layout.tsx - Add path to
SPA_ROUTESinvite.config.js
| File | Purpose |
|---|---|
components.json |
shadcn/ui configuration |
vite.config.js |
Vite build + SPA routes |
tsconfig.json |
TypeScript config |
npm start # Dev server (from root)
npm run build:website # Build website (from root)