Agent skill

nextjs-app-router

Deep expertise in Next.js App Router patterns including route groups, parallel routes, intercepting routes, layouts, and loading states.

Stars 514
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/a5c-ai/babysitter/tree/main/library/specializations/web-development/skills/nextjs-app-router

SKILL.md

Next.js App Router Skill

Expert assistance for implementing Next.js App Router with advanced routing patterns and conventions.

Capabilities

  • Design app directory structure with route groups
  • Implement parallel and intercepting routes
  • Configure layouts, templates, and loading states
  • Set up error boundaries and not-found pages
  • Implement streaming with Suspense
  • Configure route handlers for API endpoints

Usage

Invoke this skill when you need to:

  • Structure app directory for complex routing
  • Implement modal routes with interception
  • Create parallel route layouts
  • Configure streaming and loading states
  • Build API route handlers

Inputs

Parameter Type Required Description
routeType string Yes page, layout, route, loading, error
routePath string Yes Route path in app directory
features array No parallel, intercept, group
streaming boolean No Enable streaming with Suspense

Configuration Example

json
{
  "routeType": "page",
  "routePath": "/dashboard/analytics",
  "features": ["parallel", "loading"],
  "streaming": true
}

Route Structure Patterns

Route Groups

app/
├── (auth)/
│   ├── login/
│   │   └── page.tsx
│   ├── register/
│   │   └── page.tsx
│   └── layout.tsx          # Auth-specific layout
├── (dashboard)/
│   ├── analytics/
│   │   └── page.tsx
│   ├── settings/
│   │   └── page.tsx
│   └── layout.tsx          # Dashboard layout with sidebar
├── (marketing)/
│   ├── about/
│   │   └── page.tsx
│   ├── pricing/
│   │   └── page.tsx
│   └── layout.tsx          # Marketing layout
└── layout.tsx              # Root layout

Parallel Routes

app/
├── @modal/
│   ├── (.)photos/[id]/
│   │   └── page.tsx        # Modal view
│   └── default.tsx
├── @sidebar/
│   ├── default.tsx
│   └── feed/
│       └── page.tsx
├── photos/
│   └── [id]/
│       └── page.tsx        # Full page view
├── layout.tsx
└── page.tsx
typescript
// app/layout.tsx
export default function Layout({
  children,
  modal,
  sidebar,
}: {
  children: React.ReactNode;
  modal: React.ReactNode;
  sidebar: React.ReactNode;
}) {
  return (
    <html>
      <body>
        <div className="flex">
          <aside>{sidebar}</aside>
          <main>{children}</main>
        </div>
        {modal}
      </body>
    </html>
  );
}

Intercepting Routes

app/
├── @modal/
│   └── (.)photos/[id]/     # Intercept from same level
│       └── page.tsx
├── feed/
│   └── @modal/
│       └── (..)photos/[id]/ # Intercept from parent
│           └── page.tsx
└── photos/
    └── [id]/
        └── page.tsx
typescript
// app/@modal/(.)photos/[id]/page.tsx
import { Modal } from '@/components/modal';
import Photo from '@/components/photo';

export default function PhotoModal({
  params: { id },
}: {
  params: { id: string };
}) {
  return (
    <Modal>
      <Photo id={id} />
    </Modal>
  );
}

Loading and Error States

typescript
// app/dashboard/loading.tsx
export default function DashboardLoading() {
  return (
    <div className="animate-pulse">
      <div className="h-8 bg-gray-200 rounded w-1/4 mb-4" />
      <div className="h-64 bg-gray-200 rounded" />
    </div>
  );
}

// app/dashboard/error.tsx
'use client';

export default function DashboardError({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  return (
    <div className="p-4 bg-red-50 rounded">
      <h2 className="text-red-800 font-bold">Something went wrong!</h2>
      <p className="text-red-600">{error.message}</p>
      <button
        onClick={reset}
        className="mt-2 px-4 py-2 bg-red-600 text-white rounded"
      >
        Try again
      </button>
    </div>
  );
}

Route Handlers

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

export async function GET(request: NextRequest) {
  const searchParams = request.nextUrl.searchParams;
  const query = searchParams.get('query');

  const users = await db.user.findMany({
    where: query ? { name: { contains: query } } : undefined,
  });

  return NextResponse.json(users);
}

export async function POST(request: NextRequest) {
  const body = await request.json();

  const user = await db.user.create({
    data: body,
  });

  return NextResponse.json(user, { status: 201 });
}

// app/api/users/[id]/route.ts
export async function GET(
  request: NextRequest,
  { params }: { params: { id: string } }
) {
  const user = await db.user.findUnique({
    where: { id: params.id },
  });

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

  return NextResponse.json(user);
}

Streaming with Suspense

typescript
// app/dashboard/page.tsx
import { Suspense } from 'react';
import { Analytics, RecentActivity, Stats } from '@/components';
import { StatsSkeleton, ActivitySkeleton } from '@/components/skeletons';

export default function Dashboard() {
  return (
    <div className="grid gap-4">
      <Suspense fallback={<StatsSkeleton />}>
        <Stats />
      </Suspense>

      <div className="grid grid-cols-2 gap-4">
        <Suspense fallback={<ActivitySkeleton />}>
          <RecentActivity />
        </Suspense>

        <Suspense fallback={<div>Loading analytics...</div>}>
          <Analytics />
        </Suspense>
      </div>
    </div>
  );
}

Best Practices

  • Use route groups to organize without affecting URL
  • Implement loading.tsx for immediate feedback
  • Use error.tsx for graceful error handling
  • Leverage parallel routes for complex layouts
  • Use intercepting routes for modal patterns

Target Processes

  • nextjs-full-stack
  • frontend-architecture-design
  • app-router-migration
  • performance-optimization

Expand your agent's capabilities with these related and highly-rated skills.

a5c-ai/babysitter

gsd-tools

Central utility skill for GSD operations. Provides config parsing, slug generation, timestamps, path operations, and orchestrates calls to other specialized skills. Acts as the unified entry point that the original gsd-tools.cjs provided via its lib/ modules (commands, config, core, init).

514 31
Explore
a5c-ai/babysitter

model-profile-resolution

Resolve model profile (quality/balanced/budget) at orchestration start and map agents to specific models. Enables cost/quality tradeoffs by selecting appropriate AI models for each agent role.

514 31
Explore
a5c-ai/babysitter

verification-suite

Plan structure validation, phase completeness checks, reference integrity verification, and artifact existence confirmation. Provides the structured verification layer ensuring GSD artifacts are well-formed and complete.

514 31
Explore
a5c-ai/babysitter

state-management

STATE.md reading, writing, and field-level updates. Provides cross-session state persistence via .planning/STATE.md with structured fields for current task, completed phases, blockers, decisions, and quick tasks.

514 31
Explore
a5c-ai/babysitter

git-integration

Git commit patterns, formats, and conventions for GSD methodology. Provides atomic commits per task, structured commit messages, planning file commits, branch management, and milestone tag operations.

514 31
Explore
a5c-ai/babysitter

frontmatter-parsing

YAML frontmatter parsing and manipulation for .planning/ documents. Provides read, write, update, query, and validation operations on frontmatter blocks in GSD markdown artifacts.

514 31
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results