Universal AI Lib
cd ../skills

Next.js App Router Skill

Use when working on pages, layouts, routes, or data fetching in the Agentic Library app.

````instructions
# Next.js App Router Skill

## When to Use
Use when working on pages, layouts, routes, or data fetching in the Agentic Library app.

## Rules

1. **Server Components by default** — only add `'use client'` for interactive components
2. **Static generation preferred** — use `generateStaticParams` for dynamic routes
3. **Metadata via exports** — use `export const metadata` or `generateMetadata`
4. **No `useEffect` for data** — fetch in Server Components via `src/server/queries.ts`
5. **Layout nesting** — shared UI in `layout.tsx`, unique content in `page.tsx`

## Patterns

### Server Component with Data
```tsx
import { getResourcesBySection, getAllResources } from '@/server/queries';
import { SECTION_META } from '@/lib/types';

export default async function MyPage() {
  const skills = await getResourcesBySection('skill');
  return <div>{skills.map(s => <Card key={s.slug} resource={s} />)}</div>;
}
```

### Dynamic Route with Static Params
```tsx
import { getAllResources, getResourceBySlug } from '@/server/queries';

export async function generateStaticParams() {
  const resources = await getAllResources();
  return resources.map((r) => ({ slug: r.slug }));
}

export default async function DetailPage({ params }: { params: Promise<{ slug: string }> }) {
  const { slug } = await params;
  const resource = await getResourceBySlug(slug);
  if (!resource) notFound();
  return <ResourceDetail resource={resource} />;
}
```

### Client Component
```tsx
'use client';
import { useState } from 'react';

export function InteractiveWidget() {
  const [active, setActive] = useState(false);
  return <button onClick={() => setActive(!active)}>Toggle</button>;
}
```

## Anti-Patterns

### Never fetch data client-side when server works
```tsx
// BAD — unnecessary client-side fetch
'use client';
useEffect(() => { fetch('/api/resources').then(r => r.json()) }, []);

// GOOD — use the query layer in a Server Component
import { getAllResources } from '@/server/queries';
const resources = await getAllResources();
```

### Never use Pages Router patterns
```tsx
// BAD — no getServerSideProps in App Router
export async function getServerSideProps() { ... }

// GOOD — Server Component + data import
export default async function Page() {
  const data = await getResourceBySlug('my-skill');
  if (!data) notFound();
  return <div>{data.title}</div>;
}
```

## Checklist
- [ ] Server Component unless interactivity needed
- [ ] generateStaticParams for dynamic routes
- [ ] Metadata exported for SEO
- [ ] No client-side data fetching for static data
- [ ] Proper error handling with notFound()

````

How to use this skill

  1. Click "Copy" to copy the skill content.
  2. Create a folder at .github/skills/nextjs-app-router/ in your repository.
  3. Paste the content into SKILL.md inside the folder.
  4. Reference the skill name in your AI agent's instructions or copilot config.