skills/barnhardt-enterprises-inc/nextjs-15-specialist/SKILL.md
Use when working with Next.js 15 features, App Router, Server Components, Server Actions, or data fetching patterns. Ensures correct usage of Server vs Client Components and modern Next.js patterns.
npx skillsauth add aiskillstore/marketplace nextjs-15-specialistInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Complete Next.js 15 reference for Quetrex development.
This skill provides comprehensive guidance on all Next.js 15 App Router patterns, ensuring agents implement modern Next.js correctly the first time.
These rules are NON-NEGOTIABLE. Violations will break builds.
<Image> from next/image - NEVER use <img>// ✅ ALWAYS DO THIS
import Image from 'next/image'
<Image src="/logo.png" alt="Logo" width={200} height={100} />
<Image src={user.avatar} alt={user.name} width={40} height={40} />
// ❌ NEVER DO THIS - BUILD WILL FAIL
<img src="/logo.png" alt="Logo" />
<img src={user.avatar} alt={user.name} />
Why: Next.js Image component provides automatic optimization, lazy loading, and prevents layout shift. ESLint is configured to fail builds on <img> usage.
Use this skill when working with:
This skill includes comprehensive guides covering every Next.js 15 pattern:
45+ examples covering:
35+ examples covering:
35+ examples covering:
31+ examples covering:
26+ examples covering:
Executable Python script that checks:
Run with: python validate-patterns.py /path/to/src
Do you need interactivity (onClick, onChange, etc.)?
├─ YES → Client Component ('use client')
└─ NO → Server Component (default)
Do you need React hooks (useState, useEffect)?
├─ YES → Client Component
└─ NO → Server Component
Do you need browser APIs (window, localStorage)?
├─ YES → Client Component
└─ NO → Server Component
Do you need to fetch data?
├─ Use Server Component (preferred)
└─ Only use Client Component if data must be client-side
Is the component purely presentational?
└─ Server Component (better performance)
// app/projects/page.tsx
export default async function ProjectsPage() {
const projects = await db.project.findMany()
return <ProjectList projects={projects} />
}
// components/ProjectCard.tsx
'use client'
import { useState } from 'react'
export function ProjectCard({ project }: Props) {
const [loading, setLoading] = useState(false)
const handleDelete = async () => {
setLoading(true)
await deleteProject(project.id)
setLoading(false)
}
return (
<div>
<h2>{project.name}</h2>
<button onClick={handleDelete} disabled={loading}>
Delete
</button>
</div>
)
}
// app/actions.ts
'use server'
export async function createProject(formData: FormData) {
const name = formData.get('name') as string
const project = await db.project.create({ data: { name } })
revalidatePath('/projects')
return { success: true, project }
}
// app/projects/new/page.tsx
import { createProject } from '@/app/actions'
export default function NewProjectPage() {
return (
<form action={createProject}>
<input name="name" required />
<button type="submit">Create</button>
</form>
)
}
// app/dashboard/page.tsx
import { Suspense } from 'react'
export default function DashboardPage() {
return (
<div>
<Suspense fallback={<ProjectsSkeleton />}>
<ProjectsAsync />
</Suspense>
<Suspense fallback={<UsersSkeleton />}>
<UsersAsync />
</Suspense>
</div>
)
}
async function ProjectsAsync() {
const projects = await fetchProjects() // Slow query
return <ProjectList projects={projects} />
}
// app/blog/[slug]/page.tsx
import type { Metadata } from 'next'
export async function generateMetadata({
params,
}: {
params: Promise<{ slug: string }>
}): Promise<Metadata> {
const { slug } = await params
const post = await fetchPost(slug)
return {
title: post.title,
description: post.excerpt,
openGraph: {
title: post.title,
description: post.excerpt,
images: [post.coverImage],
},
}
}
// ✅ DO: Server Component (default)
export default async function ProjectsPage() {
const projects = await fetchProjects()
return <ProjectList projects={projects} />
}
// ❌ DON'T: Client Component when not needed
'use client'
export default function ProjectsPage() {
const [projects, setProjects] = useState([])
useEffect(() => {
fetchProjects().then(setProjects)
}, [])
return <ProjectList projects={projects} />
}
// Static content (cached forever)
const categories = await fetch('https://api.example.com/categories', {
cache: 'force-cache',
}).then(r => r.json())
// Dynamic content (no cache)
const user = await fetch('https://api.example.com/me', {
cache: 'no-store',
}).then(r => r.json())
// ISR (revalidate every hour)
const products = await fetch('https://api.example.com/products', {
next: { revalidate: 3600 },
}).then(r => r.json())
// app/dashboard/error.tsx
'use client'
export default function DashboardError({
error,
reset,
}: {
error: Error
reset: () => void
}) {
return (
<div>
<h2>Something went wrong!</h2>
<button onClick={reset}>Try again</button>
</div>
)
}
// app/dashboard/loading.tsx
export default function DashboardLoading() {
return <DashboardSkeleton />
}
// ✅ DO: Use next/image
import Image from 'next/image'
export function ProjectCard({ project }) {
return (
<Image
src={project.image}
alt={project.name}
width={400}
height={300}
/>
)
}
// ❌ DON'T: Use <img> tag
export function ProjectCard({ project }) {
return <img src={project.image} alt={project.name} />
}
// ❌ DON'T: This is a syntax error
'use client'
export default async function BadComponent() {
const data = await fetch('/api/data')
return <div>{data}</div>
}
// ✅ DO: Use Server Component or useEffect
export default async function GoodComponent() {
const data = await fetch('/api/data')
return <div>{data}</div>
}
// ❌ DON'T: Server Components can't use browser APIs
export default function BadComponent() {
const [state, setState] = useState(false) // Error!
return <div>{state}</div>
}
// ✅ DO: Add 'use client' directive
'use client'
export default function GoodComponent() {
const [state, setState] = useState(false)
return <div>{state}</div>
}
// ❌ DON'T: Unclear caching behavior
const data = await fetch('/api/data')
// ✅ DO: Explicit cache strategy
const data = await fetch('/api/data', {
cache: 'no-store', // or 'force-cache', or { next: { revalidate: 60 } }
})
// ❌ DON'T: Unoptimized images
<img src="/logo.png" alt="Logo" />
// ✅ DO: Use Next.js Image optimization
<Image src="/logo.png" alt="Logo" width={200} height={100} />
Solution: Add 'use client' to the component file.
Solution: Remove 'use client' or use useEffect instead of async component.
Solution: Environment variables in Client Components need NEXT_PUBLIC_ prefix.
Solution: Don't use headers() or cookies() after sending response. Call them before any streaming.
Run the pattern validator to check your code:
python .claude/skills/nextjs-15-specialist/validate-patterns.py src/
The validator checks for:
This skill ensures you:
When in doubt:
Last updated: 2025-11-23 Next.js Version: 15.5 Total Examples: 150+ Total Lines: 4,000+
development
Apple Human Interface Guidelines for content display components. Use this skill when the user asks about charts component, collection view, image view, web view, color well, image well, activity view, lockup, data visualization, content display, displaying images, rendering web content, color pickers, or presenting collections of items in Apple apps. Also use when the user says how should I display charts, what's the best way to show images, should I use a web view, how do I build a grid of items, what component shows media, or how do I present a share sheet. Cross-references: hig-foundations for color/typography/accessibility, hig-patterns for data visualization patterns, hig-components-layout for structural containers, hig-platforms for platform-specific component behavior.
tools
Automate HelpDesk tasks via Rube MCP (Composio): list tickets, manage views, use canned responses, and configure custom fields. Always search tools first for current schemas.
testing
Expert Haskell engineer specializing in advanced type systems, pure functional design, and high-reliability software. Use PROACTIVELY for type-level programming, concurrency, and architecture guidance.
tools
GraphQL gives clients exactly the data they need - no more, no less. One endpoint, typed schema, introspection. But the flexibility that makes it powerful also makes it dangerous. Without proper controls, clients can craft queries that bring down your server. This skill covers schema design, resolvers, DataLoader for N+1 prevention, federation for microservices, and client integration with Apollo/urql. Key insight: GraphQL is a contract. The schema is the API documentation. Design it carefully.