Files
stanza/apps/web/package.json
T
jake 5ca679cf32 feat: add module detail pages, ⌘K search, dynamic OG images, sitemap, and SEO groundwork for apps/web
- Add `/m/$slot/$id` route (`apps/web/src/routes/m.$slot.$id.tsx`) with `module-detail.ts` server function — full adapter switcher (peer chip rows), deps/devDeps/scripts table, env-var table, templates list with click-to-expand Shiki preview, and a "Try it" copy-command bar; new detail components land under `apps/web/src/components/detail/`
- Add ⌘K search popover (`apps/web/src/components/search/site-search.tsx`) backed by `apps/web/src/lib/module-search.ts` — fuzzy-matches id/label/description/slot exactly as the CLI does; wired into the header
- Add dynamic OG image generation via `@vercel/og` + Satori: `server/routes/og/[slot]/[id].ts` renders a per-module card, `server/routes/og.ts` renders the default fallback; both served as Nitro route handlers with appropriate CDN cache headers; OG React components in `apps/web/src/server/og-card.tsx`
- Add `server/routes/sitemap.xml.ts` (enumerates `/` + all `/m/$slot/$id` URLs from registry index) and `public/robots.txt` pointing at it
- Add `apps/web/src/lib/seo.ts` — `buildHead()` helper that emits `title`, `og:*`, `twitter:*`, and `canonical` tags; consumed by `__root.tsx`, `index.tsx`, and `m.$slot.$id.tsx`
- Extract `ModuleLogo` into `apps/web/src/components/module-logo.tsx` — shared between slot-cards and the new detail page; remove the duplicate from `slot-cards.tsx`
- Add new shadcn-style UI primitives: `command.tsx` (cmdk wrapper), `dialog.tsx`, `input-group.tsx`, `kbd.tsx`, `popover.tsx`, `textarea.tsx`
- Add `apps/web/src/server/registry-base.ts` (filesystem reads to avoid SSR loopback-fetch deadlock), `registry-index.ts`, and `module-detail.ts` as the server-side data layer
- Add `@vercel/og` and `cmdk` to `apps/web` dependencies; add `vitest run` as `pnpm test` in web package
- Mark all corresponding TODO items done
2026-05-20 19:36:34 -04:00

58 lines
1.6 KiB
JSON

{
"name": "@stanza/web",
"version": "0.1.0",
"private": true,
"license": "MIT",
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"prebuild": "./scripts/copy-registry.sh",
"start": "node .output/server/index.mjs",
"check-types": "tsc --noEmit",
"test": "vitest run"
},
"dependencies": {
"@base-ui/react": "^1.5.0",
"@fontsource-variable/geist": "^5.2.9",
"@fontsource-variable/geist-mono": "^5.2.8",
"@pierre/trees": "1.0.0-beta.4",
"@stanza/registry": "workspace:*",
"@tabler/icons-react": "^3.44.0",
"@tailwindcss/vite": "^4.3.0",
"@tanstack/react-devtools": "^0.10.5",
"@tanstack/react-router": "^1.170.5",
"@tanstack/react-router-devtools": "^1.167.0",
"@tanstack/react-router-ssr-query": "^1.167.0",
"@tanstack/react-start": "^1.168.7",
"@tanstack/router-plugin": "^1.168.7",
"@vercel/og": "^0.11.1",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"nitro": "^3.0.260429-beta",
"react": "^19.2.6",
"react-dom": "^19.2.6",
"shadcn": "^4.7.0",
"shiki": "^4.1.0",
"sonner": "^2.0.7",
"tailwind-merge": "^3.6.0",
"tailwindcss": "^4.3.0",
"tw-animate-css": "^1.4.0"
},
"devDependencies": {
"@tanstack/devtools-vite": "^0.7.0",
"@testing-library/dom": "^10.4.1",
"@testing-library/react": "^16.3.2",
"@types/node": "^25.9.1",
"@types/react": "^19.2.15",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.2",
"jsdom": "^29.1.1",
"typescript": "^6.0.3",
"vite": "^8.0.13",
"vitest": "^4.1.7",
"web-vitals": "^5.2.0"
}
}