Back to skills
SKILL.md
Nextjs Expert
ASecurityNext.js 16 в монорепо: страницы и layouts, Server/Client Components, Server Actions, metadata, next-intl-роуты. Загружай ДО правки app/**/layout.tsx, not-found.tsx, next.config.mjs и когда typecheck:tsgo даёт TS6305 не по вашим правкам, hydration mismatch на невалидной локали, nx build ходит в сеть на OIDC discovery, в standalone ECONNREFUSED/ERR_DLOPEN_FAILED при зелёной сборке.
- 6 stars
- 0 votes
- 0 copies
- 0 views
- Added October 20, 2026
Works with
Security analysis
93/100- Performs destructive filesystem operations
Pro scans all 9 files and shows the line behind each finding
npx -y skills add kamiletar/letar --skill nextjs-expert --agent claude-codeAre you the author of Nextjs Expert?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/kamiletar-nextjs-expert)---
name: nextjs-expert
description: |
Next.js 16 в монорепо: страницы и layouts, Server/Client Components, Server Actions, metadata, next-intl-роуты. Загружай ДО правки app/**/layout.tsx, not-found.tsx, next.config.mjs и когда typecheck:tsgo даёт TS6305 не по вашим правкам, hydration mismatch на невалидной локали, nx build ходит в сеть на OIDC discovery, в standalone ECONNREFUSED/ERR_DLOPEN_FAILED при зелёной сборке.
---
# Next.js Expert
Руководство по разработке Next.js приложений в монорепо Letar.
## ⚠️ Ловушки (разборы в доках)
- [nextjs-stale-dotnext-types-tsgo-ts6305](/.claude/docs/nextjs-stale-dotnext-types-tsgo-ts6305.md) — устаревший `.next/types` даёт `TS6305` в `typecheck:tsgo`
- [nextjs-root-notfound-no-root-layout](/.claude/docs/nextjs-root-notfound-no-root-layout.md) — корневой `not-found.tsx` без `app/layout.tsx`: дубль `<html>`, hydration mismatch
- [nextjs-build-time-oidc-discovery-network-dependency](/.claude/docs/nextjs-build-time-oidc-discovery-network-dependency.md) — `nx build` бьёт в сеть на OIDC discovery
- [nextjs-standalone-tracing](/.claude/docs/nextjs-standalone-tracing.md) — ECONNREFUSED/ERR_DLOPEN_FAILED при зелёном билде
- [nextjs16-turbopack-default-emotion-hydration](/.claude/docs/nextjs16-turbopack-default-emotion-hydration.md) — Turbopack + Chakra `<Global>`: hydration mismatch
## Когда использовать
- Создание новых страниц и layouts
- Работа с Server/Client Components
- Data fetching и Server Actions
- Оптимизация производительности
- SEO и metadata
- Troubleshooting Next.js
---
## Проекты Letar (Next.js 16)
| App | Порт | Особенности |
| -------------- | ---- | ------------------- |
| dashboard | 3002 | SSE, React Query |
| driving-school | 3003 | Базовый App Router |
| mandala | 3004 | SSG, OG images |
| kami | 3005 | Keystatic CMS, i18n |
---
## Quick Reference
### Создание страницы
```typescript
// app/products/page.tsx (Server Component)
export default async function ProductsPage() {
const products = await db.product.findMany()
return <ProductList products={products} />
}
// app/products/loading.tsx
export default function Loading() {
return <Skeleton />
}
// app/products/error.tsx
'use client'
export default function Error({ error, reset }) {
return <ErrorMessage error={error} onRetry={reset} />
}
```
### Server vs Client Components
```typescript
// Server Component (по умолчанию) — для данных
export default async function Page() {
const data = await fetchData() // Прямой доступ к БД
return <ClientComponent data={data} />
}
// Client Component — для интерактивности
'use client'
export function Button({ onClick }) {
const [loading, setLoading] = useState(false)
return <button onClick={onClick}>Click</button>
}
```
### Server Actions
```typescript
// app/_actions/create-product.ts
'use server'
import { revalidatePath } from 'next/cache'
import { auth } from '@/lib/auth'
import { headers } from 'next/headers'
export async function createProduct(formData: FormData) {
const session = await auth.api.getSession({ headers: await headers() })
if (!session) throw new Error('Unauthorized')
await db.product.create({ data: { ... } })
revalidatePath('/products')
}
```
### Metadata
```typescript
// Static
export const metadata: Metadata = {
title: 'Каталог',
description: 'Описание страницы',
}
// Dynamic
export async function generateMetadata({ params }: { params: Promise<{ id: string }> }): Promise<Metadata> {
const { id } = await params
const product = await getProduct(id)
return { title: product.name }
}
```
### Route Handlers (API)
```typescript
// app/api/products/route.ts
export async function GET(request: NextRequest) {
const products = await db.product.findMany()
return NextResponse.json(products)
}
export async function POST(request: NextRequest) {
const body = await request.json()
const product = await db.product.create({ data: body })
return NextResponse.json(product, { status: 201 })
}
```
---
## File Conventions
| Файл | Назначение |
| --------------- | ----------------------- |
| `page.tsx` | UI страницы |
| `layout.tsx` | Shared layout |
| `loading.tsx` | Loading UI (Suspense) |
| `error.tsx` | Error boundary |
| `not-found.tsx` | 404 страница |
| `route.ts` | API endpoint |
| `template.tsx` | Re-render при навигации |
| `proxy.ts` | Proxy (ex-middleware) |
---
## Паттерны проекта
### Структура папок
```
app/
├── [locale]/ # i18n (kami)
│ ├── layout.tsx # Провайдеры
│ ├── (auth)/ # Route group
│ │ └── sign-in/
│ ├── admin/
│ │ └── _actions/ # Server Actions
│ └── catalog/
│ ├── [id]/ # Dynamic route
│ └── _components/ # Локальные компоненты
├── _components/ # Shared компоненты
└── api/ # Route Handlers
```
### Провайдеры в Layout
```typescript
// app/[locale]/layout.tsx
import { auth } from '@/lib/auth'
import { headers } from 'next/headers'
export default async function Layout({ children }) {
const session = await auth.api.getSession({ headers: await headers() })
return (
<html>
<body>
<ColorModeProvider>
<ChakraProvider>
<QueryProvider>
{children}
</QueryProvider>
</ChakraProvider>
</ColorModeProvider>
</body>
</html>
)
}
```
### ZenStack в Server Components
```typescript
import { auth } from '@/lib/auth'
import { headers } from 'next/headers'
export default async function Page() {
const session = await auth.api.getSession({ headers: await headers() })
const db = getEnhancedPrisma(session?.user)
// Access control автоматически применяется
const products = await db.product.findMany()
}
```
---
## Ключевые команды
```bash
# Разработка
nx dev <app> # Порт — в apps/<app>/.env (PORT=)
# Сборка
nx build <app>
# Очистка кэша
rm -rf apps/<app>/.next
nx reset
```
---
## Документация
| Раздел | Описание |
| -------------------------------------------------- | --------------------------- |
| [app-router.md](reference/app-router.md) | File conventions, routing |
| [components.md](reference/components.md) | Server vs Client Components |
| [data-fetching.md](reference/data-fetching.md) | Server Actions, streaming |
| [caching.md](reference/caching.md) | Кэширование, revalidation |
| [configuration.md](reference/configuration.md) | next.config.js, proxy.ts |
| [optimization.md](reference/optimization.md) | Images, fonts, bundle |
| [metadata-seo.md](reference/metadata-seo.md) | Metadata, OG, sitemap |
| [troubleshooting.md](reference/troubleshooting.md) | Распространённые проблемы |
---
Files in this skill
- SKILL.md
- reference/app-router.md
- reference/caching.md
- reference/components.md
- reference/configuration.md
- reference/data-fetching.md
- reference/metadata-seo.md
- reference/optimization.md
- reference/troubleshooting.md
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.