Next.js Scaffolding

VerifiedSafe

Generate Next.js pages, API routes, server components, layouts, and middleware following project conventions.

Sby Skills Guide Bot
DevelopmentBeginner
7/28/2026
Claude CodeCursorWindsurf
#nextjs#scaffolding#app-router#boilerplate#code-generation

Recommended for

Automated summary

Generates production-ready Next.js code by automatically detecting the project's configuration (App Router, TypeScript, Tailwind, etc.).

Strengths

  • Auto-detection of router type, source directory, and styling tools.
  • Templates for server components, API routes, layouts, loading, and error boundaries.
  • Respects existing project conventions.

Limitations

  • Only covers standard Next.js patterns, not advanced custom setups.
  • Depends on accurate project detection (may fail with unusual folder structures).
When to use it

Use this skill when you need to quickly generate a new page, API route, layout, or other Next.js file while adhering to project conventions.

When not to use it

Avoid this skill if you need to generate code for a non-Next.js framework, or if you require highly specific customizations not covered by the templates.

Security analysis

Safe
Quality score92/100

The skill uses only safe detection commands (checking directories, grepping package.json) and generates boilerplate code. No exfiltration, destruction, or obfuscation. Allowed tools (Read, Write, Bash) are used in a controlled manner.

No concerns found

How this analysis is made

Examples

Create a new blog page
Create a new page for blog posts in the app router with metadata and a server component that fetches posts.
Add a users API route
Add an API route for users with GET and POST handlers, including error handling.
Scaffold a layout with sidebar
Scaffold a layout for the dashboard section with a sidebar navigation and content area.

name: nextjs-scaffold description: Generate Next.js pages, API routes, server components, layouts, and middleware following project conventions. Use when user says "create page", "new route", "scaffold", "generate component", "add api endpoint", "create layout", or needs any Next.js boilerplate generated. allowed-tools: Read, Write, Edit, Glob, Grep, Bash

Next.js Scaffolding

Generate production-ready Next.js code following the project's existing patterns. Auto-detects App Router vs Pages Router, TypeScript config, and styling approach.

Detection workflow

Before generating anything, detect the project's setup:

# 1. Router type
if [ -d "app" ] || [ -d "src/app" ]; then
  echo "APP_ROUTER"
elif [ -d "pages" ] || [ -d "src/pages" ]; then
  echo "PAGES_ROUTER"
fi

# 2. Source directory
if [ -d "src" ]; then
  echo "SRC_DIR=src"
else
  echo "SRC_DIR=."
fi

# 3. TypeScript
if [ -f "tsconfig.json" ]; then
  echo "TYPESCRIPT=true"
fi

# 4. Styling
if [ -f "tailwind.config.js" ] || [ -f "tailwind.config.ts" ]; then
  echo "TAILWIND=true"
fi

if ls src/**/*.module.css 2>/dev/null | head -1; then
  echo "CSS_MODULES=true"
fi

# 5. Database
grep -l "supabase" package.json 2>/dev/null && echo "SUPABASE=true"
grep -l "firebase" package.json 2>/dev/null && echo "FIREBASE=true"
grep -l "prisma" package.json 2>/dev/null && echo "PRISMA=true"

# 6. Auth
grep -l "next-auth\|@auth" package.json 2>/dev/null && echo "NEXTAUTH=true"
grep -l "@supabase/auth" package.json 2>/dev/null && echo "SUPABASE_AUTH=true"

App Router templates

Page (Server Component)

// app/{route}/page.tsx
import { Metadata } from 'next'

export const metadata: Metadata = {
  title: '{Page Title}',
  description: '{Page description}',
}

export default async function {PageName}Page() {
  // Fetch data server-side
  
  return (
    <main className="container mx-auto px-4 py-8">
      <h1 className="text-3xl font-bold">{Page Title}</h1>
    </main>
  )
}

Page with params

// app/{route}/[id]/page.tsx
interface Props {
  params: Promise<{ id: string }>
}

export default async function {Name}Page({ params }: Props) {
  const { id } = await params
  
  return (
    <main className="container mx-auto px-4 py-8">
      <h1>{id}</h1>
    </main>
  )
}

Layout

// app/{route}/layout.tsx
export default function {Name}Layout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <div>
      {children}
    </div>
  )
}

Loading state

// app/{route}/loading.tsx
export default function Loading() {
  return (
    <div className="flex items-center justify-center min-h-[50vh]">
      <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900" />
    </div>
  )
}

Error boundary

// app/{route}/error.tsx
'use client'

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  return (
    <div className="flex flex-col items-center justify-center min-h-[50vh] gap-4">
      <h2 className="text-xl font-semibold">Something went wrong</h2>
      <button
        onClick={reset}
        className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
      >
        Try again
      </button>
    </div>
  )
}

API Route (App Router)

// app/api/{name}/route.ts
import { NextRequest, NextResponse } from 'next/server'

export async function GET(request: NextRequest) {
  try {
    // Implementation
    return NextResponse.json({ data: [] })
  } catch (error) {
    console.error('[API] {name} GET error:', error)
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 }
    )
  }
}

export async function POST(request: NextRequest) {
  try {
    const body = await request.json()
    // Validate input
    // Implementation
    return NextResponse.json({ success: true }, { status: 201 })
  } catch (error) {
    console.error('[API] {name} POST error:', error)
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 }
    )
  }
}

Server Action

// app/{route}/actions.ts
'use server'

import { revalidatePath } from 'next/cache'

export async function create{Name}(formData: FormData) {
  const field = formData.get('field') as string
  
  if (!field) {
    return { error: 'Field is required' }
  }

  try {
    // Database operation
    revalidatePath('/{route}')
    return { success: true }
  } catch (error) {
    return { error: 'Failed to create' }
  }
}

Middleware

// middleware.ts (project root)
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  // Auth check example
  const token = request.cookies.get('auth-token')?.value
  
  if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url))
  }
  
  return NextResponse.next()
}

export const config = {
  matcher: ['/dashboard/:path*', '/api/:path*'],
}

Supabase integration patterns

Server-side client

// lib/supabase/server.ts
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'

export async function createClient() {
  const cookieStore = await cookies()
  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() { return cookieStore.getAll() },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) =>
            cookieStore.set(name, value, options))
        },
      },
    }
  )
}

Client-side client

// lib/supabase/client.ts
import { createBrowserClient } from '@supabase/ssr'

export function createClient() {
  return createBrowserClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
  )
}

Scaffold workflow

  1. Detect project setup (router, TS, styling, DB)
  2. Read existing similar files to match patterns
  3. Generate using the matching template
  4. Verify the file compiles: npx tsc --noEmit {file}
  5. Report what was created and where

Scope constraints

  • Always detect the project setup BEFORE generating code
  • Match existing patterns (if the project uses src/, put files there)
  • Never overwrite existing files without confirmation
  • Never generate Pages Router code for App Router projects or vice versa
  • Always include error handling in API routes
  • Always include TypeScript types when the project uses TS

From the file to a first result

The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.

View the source and supporting files

This download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.

1. Download the file

Download SKILL.md

From the root of a test project, save the file as .skill-downloads/next-js-scaffolding-ms47vp3u/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.

Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.

mkdir -p '.skill-downloads/next-js-scaffolding-ms47vp3u' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/next-js-scaffolding-ms47vp3u/download' --output '.skill-downloads/next-js-scaffolding-ms47vp3u/SKILL.md.part' && mv '.skill-downloads/next-js-scaffolding-ms47vp3u/SKILL.md.part' '.skill-downloads/next-js-scaffolding-ms47vp3u/SKILL.md'

2. Check prerequisites

Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.

Tools declared by the author (check availability in your agent): Read, Write, Edit, Glob, Grep, Bash

No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.

The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.

3. Load the skill

After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.

Claude Code
test -f '.skill-downloads/next-js-scaffolding-ms47vp3u/SKILL.md' && test -s '.skill-downloads/next-js-scaffolding-ms47vp3u/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/nextjs-scaffold' && cp -R '.skill-downloads/next-js-scaffolding-ms47vp3u' '.claude/skills/nextjs-scaffold'

Cursor
test -f '.skill-downloads/next-js-scaffolding-ms47vp3u/SKILL.md' && test -s '.skill-downloads/next-js-scaffolding-ms47vp3u/SKILL.md' && mkdir -p '.cursor/skills' && test ! -e '.cursor/skills/nextjs-scaffold' && cp -R '.skill-downloads/next-js-scaffolding-ms47vp3u' '.cursor/skills/nextjs-scaffold'

OpenSkills

OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.

Official OpenSkills installation
openskills install './.skill-downloads/next-js-scaffolding-ms47vp3u'

openskills read 'next-js-scaffolding-ms47vp3u'

Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.

For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.

openskills sync

Manual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.

4. Try a first task

Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:

Read .skill-downloads/next-js-scaffolding-ms47vp3u/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.

Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.

Related skills