AgentSkillsCN

nextjs

Next.js框架专家指南。教你如何查找最新文档、验证API接口,并利用App Router构建现代化的Web应用。涵盖文档查找策略(检查已安装版本、llms.txt、Context7)、App Router架构、Server/Client组件、路由、中间件,以及常用模式。在所有Next.js开发过程中使用此技能,确保你始终使用最新的API接口。

SKILL.md
--- frontmatter
name: nextjs
description: "Expert Next.js framework guide. Teaches how to find current documentation, verify APIs, and build modern web applications with the App Router. Covers documentation lookup strategies (installed version check, llms.txt, Context7), App Router architecture, Server/Client Components, routing, middleware, and common patterns. Use this skill for all Next.js development to ensure you're using current APIs."
license: MIT
metadata:
  author: Balazs Barta
  version: "0.1.0"

Next.js Development Skill

CRITICAL WARNING ⚠️

Everything you know about Next.js is likely outdated. Never rely on memory. Always verify against current documentation.

Next.js evolves rapidly. API changes, deprecations, and new patterns emerge frequently. Before writing any code:

  1. Check your installed version
  2. Verify the API in current docs
  3. Use the documentation lookup strategies below
  4. Test your approach before implementing widely

Documentation Lookup Guide

Follow this priority order to find accurate, current information:

Priority 1: Check Installed Version

Always start here:

bash
cat node_modules/next/package.json | grep version

This tells you which Next.js version you're working with. APIs differ significantly between versions.

Priority 2: Use llms.txt (PRIMARY METHOD)

Use this first for all documentation lookups.

Next.js provides optimized documentation in machine-readable format:

  • Index/Overview: https://nextjs.org/docs/llms.txt

    • Smaller file, loaded quickly
    • Use this first to understand structure and find relevant sections
  • Comprehensive Docs: https://nextjs.org/docs/llms-full.txt

    • Complete reference documentation
    • Use when llms.txt wasn't sufficient

Query these with WebFetch tool using specific, focused prompts:

code
WebFetch https://nextjs.org/docs/llms.txt with prompt:
"What is the current recommended approach for data fetching in the App Router?"

Priority 3: Context7 MCP (LAST RESORT ONLY)

Use only when llms.txt doesn't answer your question:

code
1. resolve-library-id("next.js") → returns library ID (e.g., /vercel/next.js)
2. get-library-docs(id, topic="routing") → get specific documentation

Context7 uses significant token budget. Prefer llms.txt first.


Quick Reference: Where to Find What

QuestionFirst CheckReference File
"What's the installed Next.js version?"node_modules/next/package.json
"How do I structure my app?"llms.txt or project-structure.mdreferences/project-structure.md
"What's the right way to fetch data now?"llms.txt (Data Fetching)llms-full.txt
"How do Client/Server Components work?"llms.txt (App Router)llms-full.txt
"I'm getting a build/runtime error"common-errors.mdreferences/common-errors.md
"How do I configure Next.js?"next-config.mdreferences/next-config.md
"How do I set up middleware?"llms.txt (Middleware)llms-full.txt
"Image/Font/Script optimization?"llms.txt (Optimization)llms-full.txt
"Dynamic routes and params?"llms.txt (App Router)references/project-structure.md
"Environment variables?"llms.txt + project-structure.mdreferences/project-structure.md

App Router Core Concepts

Directory Conventions

The App Router uses file-based routing in the app/ directory. Key files:

  • page.tsx — Renders a route. Each directory can have one.
  • layout.tsx — Wraps child routes. Shared across multiple pages.
  • loading.tsx — Suspense fallback UI while page loads.
  • error.tsx — Error boundary for this route segment.
  • not-found.tsx — Renders when route doesn't exist.
  • route.ts — API route handler (GET, POST, PUT, DELETE, etc.).
  • template.tsx — Like layout, but creates new instances for each navigation.

Route Groups

Organize routes without affecting URL structure:

code
app/
  (auth)/
    login/page.tsx       → /login
    register/page.tsx    → /register
  (marketing)/
    page.tsx             → /
    about/page.tsx       → /about

Private Folders

Prefix with _ to hide from routing:

code
app/
  _components/          → Not a route
    Button.tsx
  dashboard/page.tsx

Parallel Routes

Render multiple pages in same layout simultaneously:

code
app/
  @users/page.tsx       → {users: ...}
  @posts/page.tsx       → {posts: ...}
  layout.tsx            → receives both as props

Intercepting Routes

Intercept a route and show different UI:

code
app/
  (.)photo/[id]/page.tsx    → Intercepts /photo/[id]
  photo/[id]/page.tsx       → Fallback

Server Components vs Client Components

Server Components (Default)

tsx
// app/dashboard/page.tsx
// This is a Server Component by default
export default async function Dashboard() {
  const data = await db.query(); // ✅ Direct database access
  return <div>{data}</div>;
}

Capabilities:

  • Direct database/API access
  • Keep sensitive data server-side
  • Reduce JavaScript sent to client
  • Access backend resources directly

Client Components

tsx
// app/dashboard/chart.tsx
'use client'; // ← Required directive at top

import { useState } from 'react';

export default function Chart() {
  const [data, setData] = useState([]);
  // ✅ useState, useEffect, etc. work here
  return <div>{data}</div>;
}

When needed:

  • Interactivity: useState, useContext, event listeners
  • Browser APIs: window, localStorage, geolocation
  • Hooks: useEffect, useReducer, useCallback

Common mistake: Forgetting 'use client' when using hooks → "You're importing a component that needs useState"


Server Functions (Server Actions)

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

import { submitForm } from './actions';

export default function Form() {
  return (
    <form action={submitForm}>
      <input name="email" type="email" />
      <button type="submit">Submit</button>
    </form>
  );
}
tsx
// app/dashboard/actions.ts
'use server';

export async function submitForm(formData: FormData) {
  const email = formData.get('email');
  // ✅ Direct database access
  await db.users.create({ email });
}

Middleware Basics

Middleware runs before requests are processed:

tsx
// middleware.ts (root of project)
import { NextRequest, NextResponse } from 'next/server';

export function middleware(request: NextRequest) {
  // Runs on every request
  if (request.nextUrl.pathname.startsWith('/admin')) {
    // Protect admin routes
    const token = request.cookies.get('token');
    if (!token) {
      return NextResponse.redirect(new URL('/login', request.url));
    }
  }
  return NextResponse.next();
}

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

next.config.ts Configuration

Modern Next.js projects use next.config.ts (not .js):

typescript
// next.config.ts
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  images: {
    remotePatterns: [
      { hostname: 'cdn.example.com' },
    ],
  },
  experimental: {
    // Feature flags for upcoming APIs
  },
};

export default nextConfig;

Common configurations:

  • images.remotePatterns — Allow external image domains
  • redirects / rewrites — URL manipulation
  • headers — HTTP headers for all responses
  • environment — App-wide env vars
  • webpack — Custom webpack config (mostly for Turbopack now)

Image, Font & Script Optimization

Images

tsx
import Image from 'next/image';

export default function Hero() {
  return (
    <Image
      src="/hero.jpg"
      alt="Hero"
      width={1200}
      height={600}
      priority={true} // Load immediately
    />
  );
}

Fonts

tsx
// app/layout.tsx
import { Inter } from 'next/font/google';

const inter = Inter({ subsets: ['latin'] });

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en" className={inter.className}>
      <body>{children}</body>
    </html>
  );
}

Scripts

tsx
import Script from 'next/script';

export default function RootLayout() {
  return (
    <>
      <Script
        src="https://analytics.example.com/analytics.js"
        strategy="lazyOnload"
      />
    </>
  );
}

Common Error Index

Encountering an error? Check here first:

  • Hydration errorsreferences/common-errors.md → Hydration section
  • Module not foundreferences/common-errors.md → Build & Configuration
  • "You're importing a component that needs useState" → Check for missing 'use client'
  • "Dynamic server usage" errorreferences/common-errors.md → Data Fetching section
  • TypeScript errorsreferences/common-errors.md → Build & Configuration
  • Deployment failuresreferences/common-errors.md → Deployment section

Development Workflow

Always follow this when building:

  1. Verify the API exists

    • Check installed version: cat node_modules/next/package.json | grep version
    • Query llms.txt for the current approach
    • Don't rely on memory or old blog posts
  2. Test before implementing widely

    • Create a small test case
    • Verify it works in your Next.js version
    • Check for deprecation warnings in console
  3. Structure for App Router

    • Use page.tsx for routes
    • Use layout.tsx for shared UI
    • Mark components with 'use client' only when needed
    • Colocate components near pages
  4. Handle errors properly

    • Use error.tsx for error boundaries
    • Use not-found.tsx for 404s
    • Implement loading.tsx for Suspense fallbacks
  5. Document your decisions

    • Comment why you chose Server vs Client Component
    • Note API versions in complex areas
    • Reference the docs you checked

Resources

  • Core Documentation Lookup: See "Documentation Lookup Guide" above
  • Project Structure: references/project-structure.md
  • Common Errors: references/common-errors.md
  • next.config.ts Reference: references/next-config.md
  • Detailed Doc Lookup: references/doc-lookup.md

Key Takeaway

Next.js is powerful but changes quickly. Always verify against current documentation before implementing. The llms.txt files are your fastest, most reliable source. Use them.