| name | nextjs |
| description | Develop Next.js 16+ applications with React 19, TypeScript, Tailwind CSS v4, and tRPC. Use when working with Next.js pages, API routes, server components, or when the user mentions Next.js development. |
Next.js Development
Project Stack
- Next.js: 16.1.6 (App Router)
- React: 19.2.3
- TypeScript: 5.x
- Tailwind CSS: v4
- tRPC: 10.45.2 with React Query
- Package Manager: pnpm 9.0.0
Key Configuration
next.config.ts
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
output: 'standalone',
reactCompiler: true,
};
export default nextConfig;
Path Aliases
Development Commands
pnpm dev
pnpm build
pnpm start
pnpm lint
pnpm format
pnpm format:check
App Router Structure
src/app/
├── (dashboard)/ # Route group
│ ├── components/ # Route-specific components
│ ├── debug/
│ ├── keys/
│ ├── quotas/
│ ├── users/
│ ├── layout.tsx
│ └── page.tsx
├── api/ # API routes
├── layout.tsx # Root layout
└── globals.css # Global styles
Component Patterns
Server Component (Default)
export default async function Page() {
const data = await fetchData();
return <div>{/* render */}</div>;
}
Client Component
'use client';
import { useState } from 'react';
export function ClientComponent() {
const [state, setState] = useState();
return <div>{/* render */}</div>;
}
tRPC Integration
'use client';
import { trpc } from '@/utils/api';
export function Component() {
const { data } = trpc.dashboard.getStats.useQuery();
const mutation = trpc.apiKey.create.useMutation();
return <div>{/* render */}</div>;
}
Styling with Tailwind CSS v4
<div className="flex items-center justify-center p-4">
<div className={cn('base-classes', condition && 'conditional-class')}>
// Responsive design
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
Use cn() utility from @/lib/utils for class merging.
API Routes (tRPC)
Located in src/server/api/routers/:
import { z } from 'zod';
import { createTRPCRouter, publicProcedure } from '../trpc';
export const exampleRouter = createTRPCRouter({
getAll: publicProcedure.query(async ({ ctx }) => {
return await ctx.db.query.table.findMany();
}),
create: publicProcedure.input(z.object({ name: z.string() })).mutation(async ({ ctx, input }) => {
return await ctx.db.insert(table).values(input);
}),
});
Database (Drizzle ORM)
pnpm db:generate
pnpm db:push
pnpm db:migrate
pnpm db:seed
Best Practices
- Use Server Components by default - Only add 'use client' when needed
- Leverage tRPC for type-safe APIs - All API calls go through tRPC routers
- Keep components small and focused - Follow single responsibility principle
- Use path aliases - Import with
@/ prefix
- Format on save - Project uses Prettier for consistent formatting