ekx-nextjs-applisted
Install: claude install-skill Ekinoxis-evm/claude-skills
# Next.js (App Router)
18 of 26 projects. Versions in play span **14 → 16**, and the APIs differ in ways that
break silently. Check `package.json` before applying any pattern, and ask the
`context7` MCP server rather than answering from memory on version-specific APIs.
| Version | Where |
|---|---|
| 14 | one legacy marketing site |
| 15 | most projects |
| 16 | the newest storefronts |
---
## Layout
```
app/
layout.tsx # root: fonts, providers, metadata
page.tsx
(marketing)/ # route group — no URL segment
dashboard/
layout.tsx
page.tsx
loading.tsx # instant Suspense fallback
error.tsx # 'use client' — error boundary
api/
webhooks/stripe/route.ts
components/
ui/ # primitives
lib/
supabase/{client,server,admin}.ts
utils.ts # cn()
```
---
## Server by default
Every component is a Server Component unless it says `"use client"`. Push the boundary
**down**, not up: a page that needs one interactive button should not become a client
component wholesale.
```tsx
// app/dashboard/page.tsx — server
export default async function Page() {
const supabase = await createClient();
const { data } = await supabase.from("bookings").select("*");
return <BookingTable rows={data ?? []} />; // table can be a client component
}
```
Rules that bite:
- Server Components can't use hooks, `onClick`, or browser APIs.
- Client Components can't be `async`.
- Props crossing