prowler-cloud/prowler

nextjs-16

Next.js 16 App Router patterns.

First seen May 28, 2026

Installation

$ npx skills add prowler-cloud/prowler --skill nextjs-16

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from prowler-cloud/prowler · top by installs.

npx skills add prowler-cloud/prowler

Browse all from prowler-cloud/prowler

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 14.8K
License LICENSE
Default branch master
Open issues 142
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

Version1.0
LicenseApache-2.0
Allowed toolsRead, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
More metadata
author
prowler-cloud
version
1.0
scope
["root","ui"]
auto_invoke
App Router / Server Actions

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 4,144 B
  • docs SUMMARY.md 246 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 15 installs

SKILL.md

App Router File Conventions

app/
├── layout.tsx           # Root layout (required)
├── page.tsx             # Home page (/)
├── loading.tsx          # Loading UI (Suspense)
├── error.tsx            # Error boundary
├── not-found.tsx        # 404 page
├── (auth)/              # Route group (no URL impact)
│   ├── login/page.tsx   # /login
│   └── signup/page.tsx  # /signup
├── api/
│   └── route.ts         # API handler
└── _components/         # Private folder (not routed)

Next.js 16 Notes

  • Use proxy.ts for request-boundary logic. middleware.ts is deprecated in Next.js 16.
  • proxy.ts runs on the Node.js runtime and cannot be configured for Edge.
  • Keep proxy.ts matchers narrow. Exclude api, static files, and image assets unless the route explicitly needs proxy logic.
  • Route Handlers in app/api/**/route.ts are the right fit for health checks, webhooks, backend-for-frontend endpoints, and server-only proxy calls.

Server Components (Default)

// No directive needed - async by default
export default async function Page() {
  const data = await db.query();
  return <Component data={data} />;
}

Server Actions

"use server";

import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";

export async function createUser(formData: FormData) {
  const name = formData.get("name") as string;

  await db.users.create({ data: { name } });

  revalidatePath("/users");
  redirect("/users");
}

Data Fetching

async function Page() {
  const [users, posts] = await Promise.all([getUsers(), getPosts()]);

  return <Dashboard users={users} posts={posts} />;
}

<Suspense fallback={<Loading />}>
  <SlowComponent />
</Suspense>;

Caching and Revalidation

import { revalidatePath, revalidateTag } from "next/cache";

export async function refreshDashboard() {
  "use server";

  revalidatePath("/");
  revalidateTag("dashboard");
}
  • Use revalidatePath for route-level invalidation after mutations.
  • Use revalidateTag when data fetches share a cache tag across routes.
  • With Cache Components enabled, put "use cache" only in pure server-side cached functions. Do not cache auth, tenant-scoped, or per-user responses unless the cache key explicitly isolates them.

Route Handlers (API)

// app/api/users/route.ts
import { NextResponse } from "next/server";

export async function GET() {
  const users = await db.users.findMany();
  return NextResponse.json(users);
}

export async function POST(request: Request) {
  const body = await request.json();
  const user = await db.users.create({ data: body });
  return NextResponse.json(user, { status: 201 });
}

Proxy

// proxy.ts (root level)
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export function proxy(request: NextRequest) {
  const token = request.cookies.get("token");

  if (!token && request.nextUrl.pathname.startsWith("/dashboard")) {
    return NextResponse.redirect(new URL("/login", request.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: ["/dashboard/:path*"],
};

Metadata

export const metadata = {
  title: "My App",
  description: "Description",
};

export async function generateMetadata() {
  const product = await getProduct();
  return { title: product.name };
}

server-only Package

import "server-only";

export async function getSecretData() {
  return db.secrets.findMany();
}