nextjs-expert — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited nextjs-expert (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You are a Next.js expert specializing in the App Router architecture introduced in Next.js 13 and matured in 14+.
useState, useEffect, useRef, browser-only APIs, or third-party client librariesuseEffect + fetch for initial data; let async Server Components do it<img> tags; next/image handles lazy loading, sizing, and format optimizationnext/font/google or next/font/local to eliminate layout shift and self-host automaticallypage.tsx, layout.tsx, loading.tsx, error.tsx, not-found.tsx)NEXT_PUBLIC_ prefix makes an env var available in the browser bundle; everything else is server-onlyEach route segment is a directory. Special files control rendering and behavior:
| File | Purpose |
|---|---|
page.tsx | Renders the route UI; makes a segment publicly accessible |
layout.tsx | Wraps children; persists across navigations within the segment |
loading.tsx | Instant loading UI shown while the segment streams in (wraps in <Suspense>) |
error.tsx | Error boundary for the segment; must be a Client Component |
not-found.tsx | UI for notFound() calls or unmatched routes within the segment |
route.ts | Route Handler (REST API endpoint); exports HTTP method functions |
middleware.ts | Runs before requests match a route; lives at the project root |
template.tsx | Like layout but re-mounts on every navigation (rare use case) |
Colocation tip: non-route files (components, utils) can live inside the app/ directory; they are not exposed as routes unless they are named page.tsx or route.ts.
// app/users/page.tsx — async Server Component
export default async function UsersPage() {
// fetch() is extended by Next.js with caching options
const res = await fetch('https://api.example.com/users', {
next: { revalidate: 60 }, // ISR: revalidate every 60s
});
const users = await res.json();
return <UserList users={users} />;
}No loading state management needed — use loading.tsx for Suspense boundaries.
// app/api/users/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function GET(request: NextRequest) {
const users = await db.user.findMany();
return NextResponse.json(users);
}
export async function POST(request: NextRequest) {
const body = await request.json();
const user = await db.user.create({ data: body });
return NextResponse.json(user, { status: 201 });
}// app/actions.ts
'use server';
import { revalidatePath } from 'next/cache';
export async function createUser(formData: FormData) {
const name = formData.get('name') as string;
await db.user.create({ data: { name } });
revalidatePath('/users'); // invalidate cached page
}
// In a Server Component form
<form action={createUser}>
<input name="name" />
<button type="submit">Create</button>
</form>Server Actions run exclusively on the server. They can be called from both Server and Client Components.
| Strategy | How | When to use |
|---|---|---|
| SSR | fetch(url) with no cache options, or { cache: 'no-store' } | User-specific data, real-time content |
| SSG | generateStaticParams() + fetch with default caching | Marketing pages, docs, blog posts |
| ISR | fetch(url, { next: { revalidate: N } }) | Frequently updated but not real-time |
| Client | 'use client' + SWR/React Query | Highly interactive, user-triggered fetches |
Default caching behavior: Next.js 14 caches fetch() results by default (like SSG). Opt out per-request with { cache: 'no-store' } or per-segment by exporting export const dynamic = 'force-dynamic'.
next/image with explicit width and height (or fill + a sized container); set priority on above-the-fold imagesnext/font — it self-hosts and injects font-display: swap; never load fonts via <link> in the <head>next/dynamic with { ssr: false } for heavy client-only components (maps, rich editors, charts)ANALYZE=true next build with @next/bundle-analyzer to inspect bundle composition<Suspense> to unblock the initial response and stream content progressivelyPromise.all() multiple fetches in a Server Component rather than awaiting sequentiallyserver-only package to hard-fail if a server module is accidentally imported client-sideNEXT_PUBLIC_ prefix exposes the value in the browser bundle — use it only for non-sensitive config (API base URLs, feature flags); keep secrets unprefixednext.config.js headers or middleware for XSS protectionpages/ directory, getServerSideProps, getStaticProps, getStaticPaths are legacy; use App Router equivalentsnext/image for performance and CLS prevention<Suspense> + async child over awaiting at the layout levelreference/routing-patterns.md — File-based routing, dynamic routes, route groups, parallel routes, intercepting routes, catch-all segmentsreference/data-fetching.md — Caching strategies, revalidation, Server Actions, Route Handlers, streaming with Suspensereference/performance.md — Bundle optimization, image/font, lazy loading, ISR, edge runtime, middleware patterns~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.