Files
stanza/apps/web/vite.config.ts
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

22 lines
753 B
TypeScript

import { fileURLToPath } from "node:url";
import tailwindcss from "@tailwindcss/vite";
import { devtools } from "@tanstack/devtools-vite";
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
import react from "@vitejs/plugin-react";
import { nitro } from "nitro/vite";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [nitro(), devtools(), tailwindcss(), tanstackStart(), react()],
resolve: {
tsconfigPaths: true,
},
// `serverDir: "./server"` opts Nitro into scanning `./server/routes/` (and
// `api/`, `middleware/`, `utils/`, etc) for filesystem-routed handlers. This
// is how the `/og/$slot/$id` and `/sitemap.xml` endpoints get registered.
nitro: {
serverDir: "./server",
},
});