Back to Skills

route-handlers

verified

This skill should be used when the user asks to "create an API route", "add an endpoint", "build a REST API", "handle POST requests", "create route handlers", "stream responses", or needs guidance on Next.js API development in the App Router.

View on GitHub

Marketplace

buildwithclaude

davepoon/buildwithclaude

Plugin

nextjs-expert

skills

Repository

davepoon/buildwithclaude
2.3kstars

plugins/nextjs-expert/skills/route-handlers/SKILL.md

Last Verified

January 16, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/davepoon/buildwithclaude/blob/main/plugins/nextjs-expert/skills/route-handlers/SKILL.md -a claude-code --skill route-handlers

Installation paths:

Claude
.claude/skills/route-handlers/
Powered by add-skill CLI

Instructions

# Next.js Route Handlers

## Overview

Route Handlers allow you to create API endpoints using the Web Request and Response APIs. They're defined in `route.ts` files within the `app` directory.

## Basic Structure

### File Convention

Route handlers use `route.ts` (or `route.js`):

```
app/
├── api/
│   ├── users/
│   │   └── route.ts      # /api/users
│   └── posts/
│       ├── route.ts      # /api/posts
│       └── [id]/
│           └── route.ts  # /api/posts/:id
```

### HTTP Methods

Export functions named after HTTP methods:

```tsx
// app/api/users/route.ts
import { NextResponse } from 'next/server'

export async function GET() {
  const users = await db.user.findMany()
  return NextResponse.json(users)
}

export async function POST(request: Request) {
  const body = await request.json()
  const user = await db.user.create({ data: body })
  return NextResponse.json(user, { status: 201 })
}
```

Supported methods: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD`, `OPTIONS`

## Request Handling

### Reading Request Body

```tsx
export async function POST(request: Request) {
  // JSON body
  const json = await request.json()

  // Form data
  const formData = await request.formData()
  const name = formData.get('name')

  // Text body
  const text = await request.text()

  return NextResponse.json({ received: true })
}
```

### URL Parameters

Dynamic route parameters:

```tsx
// app/api/posts/[id]/route.ts
interface RouteContext {
  params: Promise<{ id: string }>
}

export async function GET(
  request: Request,
  context: RouteContext
) {
  const { id } = await context.params
  const post = await db.post.findUnique({ where: { id } })

  if (!post) {
    return NextResponse.json(
      { error: 'Not found' },
      { status: 404 }
    )
  }

  return NextResponse.json(post)
}
```

### Query Parameters

```tsx
export async function GET(request: Request) {
  const { searchParams } = new URL(request.url)
  const page = searchParams.get('page') ?? '1'
  const limit 

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
6038 chars