Files
agentic-dev/apps/web-tanstack/AGENTS.md

119 lines
3.6 KiB
Markdown

# AGENTS.md — apps/web-tanstack
TanStack Start reference application using TanStack Router with file-based routing. Demonstrates that feature packages are framework-agnostic by consuming the same features as Next.js (via `@repo/core-api`) using TanStack's architecture instead.
## Purpose
Proof that features are framework-portable. This app consumes the exact same feature packages and tRPC routers as `apps/web-next`, but through TanStack Start's server/client architecture instead of Next.js App Router.
## Port: 3002
```bash
pnpm dev --filter @repo/web-tanstack # http://localhost:3002
```
Requires tRPC endpoint (from `apps/web-next` or another backend):
```bash
pnpm dev --filter @repo/web-next # Serves tRPC at http://localhost:3000/api/trpc
pnpm dev --filter @repo/web-tanstack # http://localhost:3002
```
## Key Files
| File | Purpose |
|---|---|
| `src/routes/__root.tsx` | Root layout — wraps all routes with `<TrpcProvider>` from `@repo/core-trpc/tanstack` |
| `src/routes/index.tsx` | Home page (`/`) |
| `src/routes/blog/index.tsx` | Blog listing (`/blog`) |
| `src/routes/blog/$slug.tsx` | Dynamic blog post (`/blog/:slug`) |
| `e2e/` | Playwright end-to-end tests |
## File-Based Routing
TanStack Router uses file-based routing where file paths map directly to URL routes:
| File | URL |
|---|---|
| `src/routes/__root.tsx` | Root (all routes) |
| `src/routes/index.tsx` | `/` |
| `src/routes/blog/index.tsx` | `/blog` |
| `src/routes/blog/$slug.tsx` | `/blog/:slug` |
Naming conventions:
- `__root.tsx` — special root layout
- `index.tsx` — index route for its directory
- `$paramName.tsx` — dynamic segment
## tRPC Setup
The root route wraps with `<TrpcProvider>`:
```typescript
// src/routes/__root.tsx
import { TrpcProvider } from "@repo/core-trpc/tanstack";
import { Outlet } from "@tanstack/react-router";
export const Route = createRootRoute({
component: () => (
<TrpcProvider trpcUrl="http://localhost:3000/api/trpc">
<Outlet />
</TrpcProvider>
),
});
```
Note: `trpcUrl` must point to a running tRPC endpoint (e.g., from `apps/web-next`).
## Fetching data in routes
```typescript
// src/routes/blog/$slug.tsx
import { createFileRoute } from "@tanstack/react-router";
import { useTRPC } from "@repo/core-trpc";
import { useQuery } from "@tanstack/react-query";
export const Route = createFileRoute("/blog/$slug")({
component: BlogPostPage,
});
function BlogPostPage() {
const { slug } = Route.useParams();
const trpc = useTRPC();
const { data, isLoading } = useQuery(
trpc.blog.getBySlug.queryOptions({ slug })
);
if (isLoading) return <p>Loading...</p>;
return <article>{data?.title}</article>;
}
```
## Dependencies
| Dependency | Purpose |
|---|---|
| `@repo/core-api` | AppRouter type (via core-trpc) |
| `@repo/core-trpc/tanstack` | TanStack tRPC client + provider |
| `@repo/core-ui` | Design system components |
| `@tanstack/react-router` | File-based routing |
| `@tanstack/react-query` | Data fetching + caching |
| `react` / `react-dom` | React 19 runtime |
## Test conventions
- e2e tests in `e2e/` folder: `*.spec.ts`
- Playwright config in `e2e/playwright.config.ts`
- Run: `pnpm test:e2e` (both Next.js and TanStack)
Parallel to `apps/web-next` e2e: validates that features work across frameworks.
## Cross-References
- **Feature packages:** `packages/{auth,blog,media,marketing-pages,navigation}/`
- **tRPC composition:** `packages/core-api/AGENTS.md`
- **tRPC client + provider:** `packages/core-trpc/AGENTS.md`
- **UI components:** `packages/core-ui/AGENTS.md`
- **Next.js app (serves tRPC):** `apps/web-next/AGENTS.md`