| name | nextjs-dev |
| description | Build Next.js App Router web features with Server Components, server actions, data fetching, Suspense streaming, middleware, SEO metadata, and deployment to Vercel or AWS. Use this skill whenever someone asks to build a server-rendered page, create a server component, implement a server action, set up Next.js routing, configure ISR/SSG, or says things like "create a server component for X", "build the SSR page", "add a server action", "set up Next.js middleware", "configure ISR for Y", "deploy to Vercel", or "add SEO metadata". Also trigger when someone mentions App Router patterns, Server vs Client Components, streaming with Suspense, or Next.js deployment. |
| model | sonnet |
Next.js (App Router) Developer
Build production-ready Next.js web features using the App Router with Server Components, server actions, Suspense streaming, and Tailwind CSS. All features consume the shared Rails API backend.
the std-nextjs skill
Development Workflow
Step 1: Understand the Feature
- Clarify the page structure and URL hierarchy.
- Determine which parts need server rendering (SEO, initial data) vs client interactivity.
- Identify data sources — Rails API endpoints, ISR revalidation strategy.
- Determine if server actions are needed for mutations.
- Check if middleware is required (auth, locale, redirects).
Step 2: Define Domain Types
Same as ReactJS SPA — create in next/src/domain/ or next/src/types/:
export interface Order { id: string; status: OrderStatus; totalAmount: number; }
export type OrderStatus = 'pending' | 'confirmed' | 'shipped' | 'delivered' | 'cancelled';
Step 3: Build Server Component Pages
import type { Metadata } from 'next';
import { OrderTable } from '@/components/OrderTable';
import { railsApi } from '@/api/client';
export const metadata: Metadata = {
title: 'Orders | MyApp',
description: 'View and manage your orders',
};
export const revalidate = 60;
export default async function OrdersPage() {
const orders = await railsApi.get('/api/v1/orders');
return (
<div className="space-y-6">
<h1 className="text-2xl font-bold">Orders</h1>
<OrderTable initialData={orders} />
</div>
);
}
Step 4: Build Server Actions
Create server actions in next/src/actions/ for mutations:
'use server';
import { revalidatePath } from 'next/cache';
import { z } from 'zod';
const CreateOrderSchema = z.object({ });
export async function createOrder(prevState: unknown, formData: FormData) {
const parsed = CreateOrderSchema.safeParse(Object.fromEntries(formData));
if (!parsed.success) return { errors: parsed.error.flatten().fieldErrors };
revalidatePath('/orders');
return { success: true };
}
Step 5: Add Loading and Error Boundaries
export default function OrdersLoading() {
return <OrderTableSkeleton />;
}
'use client';
export default function OrdersError({ error, reset }: { error: Error; reset: () => void }) {
return (
<div className="text-center">
<p className="text-red-600">Failed to load orders</p>
<button onClick={reset} className="mt-2 text-blue-600 underline">Try again</button>
</div>
);
}
Step 6: Add Client Components (When Needed)
Extract interactive parts into separate Client Components:
'use client';
import { useRouter, useSearchParams } from 'next/navigation';
export function OrderFilters() {
const router = useRouter();
const searchParams = useSearchParams();
}
Step 7: Configure Metadata and SEO
- Every page exports
metadata or generateMetadata.
- Dynamic pages use
generateMetadata with data fetching.
- Add Open Graph and Twitter card metadata for social sharing.
- Set canonical URLs to prevent duplicate content.
Step 8: Add Middleware (If Needed)
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('auth_token');
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url));
}
}
Step 9: Testing
- Server Components: Test as async functions — call and assert on returned JSX.
- Server Actions: Test as async functions with FormData input.
- Client Components: Test with React Testing Library (same as ReactJS SPA).
- MSW for mocking Rails API responses.
Step 10: Deployment
Vercel
npm i -g vercel
vercel
vercel --prod
AWS ECS (standalone)
next build
docker build -t myapp-next .
Checklist Before Done
Deep guides (read on demand, do not preload)
- Server Component pages,
generateMetadata, server actions with validation + revalidation, Route Handlers (BFF) → references/server-patterns.md
- Progressive-enhancement forms, Client Components with TanStack Query →
references/client-patterns.md
- Root layout providers, loading/error boundaries, auth+locale middleware, Server Component and server-action tests →
references/infrastructure-patterns.md
Owned by std-nextjs (scoped to App Router work)
This targets Next.js 15+. That is not a footnote: 15 changed caching defaults and request
APIs, so the same code behaves differently on 14 — fetch is not cached by default,
GET route handlers are not cached, and cookies()/params are async
(await params, await cookies()). Guidance that does not say which major it means is guidance
you cannot check. The version table and both consequences live in the std-nextjs skill body.
- Choosing the Server/Client boundary →
@skills/std-nextjs/references/rendering.md
- Server actions: writing mutations →
@skills/std-nextjs/references/server-actions.md
- Caching, ISR, revalidation →
@skills/std-nextjs/references/caching.md
- Middleware, SEO metadata, deployment →
@skills/std-nextjs/references/middleware-seo-deploy.md