agent-rules-kit
Version:
Bootstrap of **Cursor** rules (`.mdc`) and mirror documentation (`.md`) for AI agent-guided projects.
151 lines (115 loc) • 4.19 kB
Markdown
---
description: App Router architecture guidelines for Next.js 13+
globs: <root>/app/**/*.ts,<root>/app/**/*.tsx
alwaysApply: false
---
# Next.js App Router Guidelines
This project uses Next.js App Router (introduced in Next.js 13). Follow these conventions for consistency.
## Directory Structure
```
app/
├── api/ # API routes (Server Components/Route Handlers)
├── (auth)/ # Auth group (route groups with parentheses don't affect URL paths)
│ ├── login/ # /login route
│ └── register/ # /register route
├── dashboard/ # /dashboard route
│ ├── page.tsx # Main dashboard page component
│ ├── layout.tsx # Dashboard layout wrapper
│ ├── loading.tsx # Loading UI
│ └── error.tsx # Error UI
├── blog/
│ ├── [slug]/ # Dynamic route segment
│ │ └── page.tsx # Blog post page
│ └── page.tsx # Blog index page
├── page.tsx # Home page (/)
├── layout.tsx # Root layout
└── not-found.tsx # Custom 404 page
```
## File Conventions
- **page.tsx**: The UI for a route segment
- **layout.tsx**: Shared UI for a segment and its children
- **loading.tsx**: Loading UI for a segment
- **error.tsx**: Error UI for a segment
- **not-found.tsx**: UI for 404 errors
- **route.ts/js**: API endpoint for a route segment
## Server and Client Components
By default, all components in the App directory are React Server Components. Use the "use client" directive to opt into client-side rendering:
```tsx
// A server component (default)
export default function ServerComponent() {
// Can use async/await and server-only data fetching
// CANNOT use hooks or browser APIs
return <div>Server-rendered content</div>;
}
// A client component
('use client');
import { useState } from 'react';
export default function ClientComponent() {
// Can use hooks and browser APIs
// CANNOT use async/await directly in component
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}
```
## Data Fetching
Use the built-in data fetching methods in Server Components:
```tsx
async function getData() {
const res = await fetch('https://api.example.com/data');
if (!res.ok) {
throw new Error('Failed to fetch data');
}
return res.json();
}
export default async function Page() {
const data = await getData();
return <main>{/* Use data */}</main>;
}
```
## Route Handlers
Route handlers (API routes) should be in `app/api` or alongside your pages:
```tsx
// app/api/users/route.ts
import { NextResponse } from 'next/server';
export async function GET() {
const users = await fetchUsers();
return NextResponse.json(users);
}
export async function POST(request: Request) {
const data = await request.json();
const newUser = await createUser(data);
return NextResponse.json(newUser, { status: 201 });
}
```
## Best Practices
1. **Co-locate related files**: Keep page, layout, loading, and error handling files together
2. **Use route groups**: Organize routes with similar features using route groups (parentheses)
3. **Parallel routes**: For complex layouts with independent loading states, use parallel routes (@folder)
4. **Interception routes**: Intercept routes for modals using (.) or (..) in folder names
5. **Prefer Server Components**: Default to using Server Components unless you need client-side interactivity
6. **Create small, focused client components**: Move client-only logic into small, focused components
7. **Use streaming**: When appropriate, stream in UI with loading.tsx and Suspense boundaries
## Metadata
Set metadata in page or layout files:
```tsx
export const metadata = {
title: 'Page Title',
description: 'Page description',
};
export default function Page() {
// ...
}
```
## Navigation
Use the Link component for client-side navigation:
```tsx
import Link from 'next/link';
export default function Navigation() {
return (
<nav>
<Link href='/'>Home</Link>
<Link href='/dashboard'>Dashboard</Link>
</nav>
);
}
```