Claude Code Plugins

Community-maintained marketplace

Feedback

nextjs-api-routes

@CoderMariusz/MonoPilot
1
0

Apply when building API endpoints in Next.js App Router using Route Handlers.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name nextjs-api-routes
description Apply when building API endpoints in Next.js App Router using Route Handlers.
version 1.0.0
tokens ~650
confidence high
sources https://nextjs.org/docs/app/building-your-application/routing/route-handlers, https://nextjs.org/docs/app/api-reference/functions/next-request
last_validated Fri Jan 10 2025 00:00:00 GMT+0000 (Coordinated Universal Time)
next_review Fri Jan 24 2025 00:00:00 GMT+0000 (Coordinated Universal Time)
tags nextjs, api, routes, backend

When to Use

Apply when building API endpoints in Next.js App Router using Route Handlers.

Patterns

Pattern 1: Basic Route Handler

// Source: https://nextjs.org/docs/app/building-your-application/routing/route-handlers
// app/api/users/route.ts
import { NextRequest, NextResponse } from 'next/server';

export async function GET(request: NextRequest) {
  const users = await db.users.findMany();
  return NextResponse.json(users);
}

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

Pattern 2: Dynamic Route Parameters

// Source: https://nextjs.org/docs/app/building-your-application/routing/route-handlers
// app/api/users/[id]/route.ts
interface RouteParams {
  params: Promise<{ id: string }>;
}

export async function GET(request: NextRequest, { params }: RouteParams) {
  const { id } = await params;
  const user = await db.users.findUnique({ where: { id } });

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

export async function DELETE(request: NextRequest, { params }: RouteParams) {
  const { id } = await params;
  await db.users.delete({ where: { id } });
  return new NextResponse(null, { status: 204 });
}

Pattern 3: Query Parameters & Headers

// Source: https://nextjs.org/docs/app/api-reference/functions/next-request
export async function GET(request: NextRequest) {
  // Query params
  const searchParams = request.nextUrl.searchParams;
  const page = parseInt(searchParams.get('page') || '1');
  const limit = parseInt(searchParams.get('limit') || '10');

  // Headers
  const authHeader = request.headers.get('authorization');
  if (!authHeader) {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
  }

  const data = await db.items.findMany({
    skip: (page - 1) * limit,
    take: limit,
  });

  return NextResponse.json({ data, page, limit });
}

Pattern 4: Error Handling Pattern

// Source: https://nextjs.org/docs/app/building-your-application/routing/route-handlers
export async function POST(request: NextRequest) {
  try {
    const body = await request.json();

    // Validation
    const result = schema.safeParse(body);
    if (!result.success) {
      return NextResponse.json(
        { error: 'Validation failed', details: result.error.flatten() },
        { status: 400 }
      );
    }

    const item = await db.items.create({ data: result.data });
    return NextResponse.json(item, { status: 201 });

  } catch (error) {
    console.error('API Error:', error);
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 }
    );
  }
}

Pattern 5: CORS Headers

// Source: https://nextjs.org/docs/app/building-your-application/routing/route-handlers
export async function OPTIONS() {
  return new NextResponse(null, {
    status: 204,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type, Authorization',
    },
  });
}

Anti-Patterns

  • Business logic in route handlers - Extract to service layer
  • No error handling - Always wrap in try/catch
  • Returning errors as 200 - Use appropriate status codes
  • No input validation - Always validate with Zod

Verification Checklist

  • All routes have error handling
  • Input validated before processing
  • Correct HTTP status codes used
  • Auth checked where required
  • CORS configured if needed