Skip to content
cccskills
FreePublished on GitHub

nextjs-app-router

Next.js App Router patterns and best practices

The English summary is being prepared. Showing the original description.

See how to install

Files included (1)

  • SKILL.md4.8 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Next.js App Router Skill

Advanced Next.js App Router patterns, data fetching, and optimization.

When to use this skill

  • Creating new pages and layouts
  • Implementing data fetching
  • Setting up API routes
  • Optimizing performance

Patterns

1. Layout with Nested Routes

// app/dashboard/layout.tsx
export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className="flex">
      <aside className="w-64 border-r">
        <nav>{/* Navigation */}</nav>
      </aside>
      <main className="flex-1 p-8">{children}</main>
    </div>
  );
}

2. Server Components with Data Fetching

// app/posts/page.tsx
async function getPosts() {
  const res = await fetch('https://api.example.com/posts', {
    next: { revalidate: 3600 }
  });
  return res.json();
}

export default async function PostsPage() {
  const posts = await getPosts();

  return (
    <div>
      <h1>Posts</h1>
      {posts.map((post) => (
        <article key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.excerpt}</p>
        </article>
      ))}
    </div>
  );
}

3. Client Components with Interactivity

// app/counter/page.tsx
'use client';

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

4. API Routes with Validation

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

const UserSchema = z.object({
  name: z.string().min(1),
  email: z.string().email()
});

export async function POST(request: NextRequest) {
  try {
    const body = await request.json();
    const validated = UserSchema.parse(body);
    
    // Create user
    const user = await createUser(validated);
    
    return NextResponse.json({ user }, { status: 2101 });
  } catch (error) {
    if (error instanceof z.ZodError) {
      return NextResponse.json(
        { error: 'Validation failed', details: error.errors },
        { status: 400 }
      );
    }
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 }
    );
  }
}

5. Dynamic Routes with Loading States

// app/posts/[id]/loading.tsx
export default function Loading() {
  return <div>Loading post...</div>;
}

// app/posts/[id]/error.tsx
'use client';

export default function Error({ error, reset }) {
  return (
    <div>
      <h2>Something went wrong!</h2>
      <button onClick={() => reset()}>Try again</button>
    </div>
  );
}

// app/posts/[id]/page.tsx
async function getPost(id: string) {
  const res = await fetch(`https://api.example.com/posts/${id}`);
  if (!res.ok) throw new Error('Failed to fetch post');
  return res.json();
}

export default async function PostPage({
  params,
}: {
  params: { id: string };
}) {
  const post = await getPost(params.id);

  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </article>
  );
}

6. Parallel Routes

// app/dashboard/layout.tsx
export default function DashboardLayout({
  children,
  analytics,
  notifications,
}: {
  children: React.ReactNode;
  analytics: React.ReactNode;
  notifications: React.ReactNode;
}) {
  return (
    <div className="flex">
      <div className="flex-1">{children}</div>
      <div className="w-64">
        {analytics}
        {notifications}
      </div>
    </div>
  );
}

// app/dashboard/@analytics/page.tsx
export default function Analytics() {
  return <div>Analytics content</div>;
}

// app/dashboard/@notifications/page.tsx
export default function Notifications() {
  return <div>Notifications content</div>;
}

7. Intercepting Routes

// app/feed/(..)photo/[id]/page.tsx
export default function PhotoModal({ params }) {
  return (
    <div className="modal">
      <h1>Photo {params.id}</h1>
      {/* Modal content */}
    </div>
  );
}

8. Metadata and SEO

// app/posts/[id]/page.tsx
import { Metadata } from 'next';

export async function generateMetadata({
  params,
}: {
  params: { id: string };
}): Promise<Metadata> {
  const post = await getPost(params.id);
  
  return {
    title: post.title,
    description: post.excerpt,
    openGraph: {
      title: post.title,
      description: post.excerpt,
      images: [post.image]
    }
  };
}

export default async function PostPage({ params }) {
  const post = await getPost(params.id);
  return <article>{/* Content */}</article>;
}

Checklist

  • Layouts properly structured
  • Data fetching optimized
  • Loading and error states handled
  • API routes validated
  • SEO metadata configured
  • Performance optimized

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Audit and fix accessibility issues across the portfolio to ensure WCAG 2.1 AA compliance.

The English summary is being prepared. Showing the original description.

PP-Namias/Portfolio2Updated Oct 23, 2026

Creates a new blog post document in the Sanity studio. Use when the user wants to write a blog post, publish an article, or schedule a future post.

The English summary is being prepared. Showing the original description.

PP-Namias/Portfolio2Updated Oct 23, 2026

Creates a new certification document in the Sanity studio. Use when the user wants to add a credential, certificate, or professional accreditation to the Certifications collection.

The English summary is being prepared. Showing the original description.

PP-Namias/Portfolio2Updated Oct 23, 2026

Adds a new skill MD file to the studio's skills collection. Use when the user wants to author a new step-by-step recipe for the studio's in-app Skills tool or the .agents mirror.

The English summary is being prepared. Showing the original description.

PP-Namias/Portfolio2Updated Oct 23, 2026

Creates a new project document in the Sanity studio. Use when the user wants to add a new portfolio project, a case study, or a work sample to the Projects collection.

The English summary is being prepared. Showing the original description.

PP-Namias/Portfolio2Updated Oct 23, 2026

Creates a new experience document in the Sanity studio. Use when the user wants to add a job, role, internship, or work history entry to the Experience collection.

The English summary is being prepared. Showing the original description.

PP-Namias/Portfolio2Updated Oct 23, 2026

See all skills by PP-Namias

Report a problem with this skill