All posts
prompt-engineeringnextjsllm

Next.js App Router Prompts: Ready-to-Use Templates

Copy-paste next.js app router prompts with real examples, plus what to change for your own use case.

SR

Suhail Roushan

August 6, 2026

·
6 min read
·
0 views

These Next.js App Router prompts solve the most common failure mode: LLMs generating Pages Router code or making up file conventions. I've tested these with Claude, GPT-4, Gemini, and DeepSeek — they work best when you paste them verbatim. Next.js App Router Prompts need explicit context about server components, layouts, and route handlers, or you'll get plausible-looking code that crashes at runtime.

Why Generic Prompts Fail Here

The App Router changed everything — file conventions, data fetching, caching. A generic prompt like "build a blog" makes the LLM default to the Pages Router patterns it was trained on. You get getServerSideProps, _app.tsx, and client-side fetching where you need server components. The failure mode isn't bad code — it's confident, wrong code. The LLM doesn't know it's wrong because it's pattern-matching on older training data.

The fix is forcing the model into App Router constraints before it starts generating. These prompts do that by naming exact files, specifying server vs. client boundaries, and requiring specific imports.

Template 1: Route Handler Boilerplate

Use this when you need a POST endpoint that handles authentication and database writes. Replace the placeholders with your actual schema and auth method.

You are a senior Next.js developer working exclusively with the App Router (Next.js 14+).
Create a route handler at app/api/[resource]/route.ts that:
1. Accepts POST requests with a JSON body
2. Validates the body against this Zod schema: [INSERT SCHEMA]
3. Authenticates using [INSERT AUTH METHOD - e.g., getServerSession from next-auth]
4. Returns 401 on auth failure, 400 on validation failure, 201 on success
5. Uses the `NextResponse` API — do NOT use the deprecated `pages/api` handlers

Structure the file with:
- Explicit type annotations for Request and Params
- A named `POST` export (no default export)
- try/catch wrapping the database call
- Proper error logging with console.error

Write the complete file. Include all imports.

Placeholders: [resource] — your API path segment; [INSERT SCHEMA] — your Zod schema; [INSERT AUTH METHOD] — your auth provider's session hook.

Template 2: Server Component with Parallel Data Fetching

For pages that need multiple data sources without waterfall loading. This template enforces the right patterns for server components and Suspense boundaries.

Act as a Next.js App Router expert. Build a server component at app/[section]/page.tsx that:
1. Fetches two independent data sources in parallel using Promise.all
2. Wraps each data-dependent child in its own <Suspense> boundary
3. Uses the `searchParams` prop for query string handling — NOT useSearchParams (that's for client components)
4. Includes a loading.tsx file that shows skeleton UI for the page
5. Handles the case where searchParams is a Promise (Next.js 15 behavior)

Requirements:
- All data fetching happens in the server component — zero client-side fetching
- Use the native fetch API with `{ next: { revalidate: 60 } }` for ISR-style caching
- Export a `metadata` object with dynamic title based on the section param
- Type the params and searchParams props explicitly

Provide both files: page.tsx and loading.tsx.

Note: If your project runs Next.js 15, the searchParams Promise behavior is non-negotiable. I've seen LLMs skip this and generate code that type-checks but fails in production.

Template 3: Client Component Wrapping Server Data

The hardest pattern to get right — passing server data into interactive components. This template handles the edge case where you need client-side state on top of server-fetched data.

You're building a Next.js App Router feature. Create:
1. A server component (app/dashboard/page.tsx) that fetches user data and recent activity in parallel
2. A client component (app/dashboard/activity-filters.tsx) that receives the activity data as props

The client component must:
- Use the "use client" directive at the top
- Accept a typed `initialData` prop (define the type explicitly)
- Implement client-side filtering with useState — do NOT refetch data
- Include a reset button that clears all filters
- NOT import any server-only modules (fs, path, database clients)

The server component must:
- Pass serialized data as props — no functions, no Date objects (they don't serialize)
- Use `import type` for any shared types between the two files
- Include error.tsx and not-found.tsx for the route

Write both files completely, plus the shared type definition.

The "no Date objects" constraint matters — LLMs love passing new Date() from server to client, and it breaks hydration. This template catches that before you debug it for an hour.

How to Adapt These for Your Own Codebase

First, replace every placeholder with your actual schema, auth method, or data shape before sending. A prompt with [INSERT SCHEMA] gives you generic Zod code; a prompt with your real schema gives you production code.

Second, add your project's specific constraints. If you use tRPC, Drizzle, or a custom fetch wrapper, append one line: "Use [library] for all data access" — that single sentence prevents the LLM from inventing its own data layer.

Third, demand file paths. LLMs generate better code when you specify the exact route (app/dashboard/settings/page.tsx) rather than a vague component name. It forces the model to think in App Router terms.

Finally, check the generated code for the three most common hallucinations: getServerSideProps (Pages Router), next/router imports, and missing "use client" directives. These three account for 80% of broken App Router output I've seen.

Do These Prompts Work With Any LLM?

Yes, but with caveats. Claude and GPT-4 handle the multi-file generation best — they produce coherent code across the server/client boundary. Gemini is solid for single-file templates like the route handler. DeepSeek works but needs the constraints repeated — it tends to drift toward Pages Router patterns if the prompt is long. I've also found that adding "Next.js 14+ App Router" to the first line improves output across all models, since it anchors the training context. For the best results, keep each prompt to one file or one feature — multi-file prompts degrade quality on every model I've tested.

The one adjustment that improves these prompts the most: include your actual TypeScript types in the prompt instead of placeholder names. A prompt with real types produces code that compiles on the first try — that's worth more than any other tweak.

Related posts

Written by Suhail Roushan — Full-stack developer. More posts on AI, Next.js, and building products at suhailroushan.com/blog.

Get in touch