with one click
nextjs-patterns
Next.js best practices, server components, app router patterns, caching strategies, and full-stack architecture
Menu
Next.js best practices, server components, app router patterns, caching strategies, and full-stack architecture
Generate a 15-30 second scrolling video tour of any GitHub repository page with ElevenLabs AI narration and word-by-word subtitle sync. Captures a full-page mobile-viewport screenshot, scrolls top-to-bottom with GSAP, and burns synced subtitles onto the final MP4 using HyperFrames CLI.
Lightweight personal knowledge base — markdown + YAML frontmatter structured notes with full-text search and cross-referencing for AI agents
Automated daily tech briefing — multi-source collection → knowledge-base deduplication → AI summarization → TTS speech synthesis, generating MP3 audio briefings
Generate 1080x1920 Instagram Reels video promos for GitHub repositories using HyperFrames. 7-beat structure with fullscreen scrolling phone mockup, GSAP animations, dark GitHub theme, repo stats, ElevenLabs AI voiceover synced to scroll duration, and follow CTA. Depends on the website-to-hyperframes skill for HyperFrames composition patterns.
Design safe X/Twitter automation workflows for tweet search, reply reads, monitoring, posting, and agent-operated social media actions
Assess worker classification and compliance risk for temporary event staffing in the US and Canada. Use when a user asks about W-2 vs 1099 event workers, misclassification penalties, joint-employer liability, COI requirements, or wage/hour rules for event staff. Includes live state-by-state lookups via the TempGuru MCP server.
| name | nextjs-patterns |
| description | Next.js best practices, server components, app router patterns, caching strategies, and full-stack architecture |
| metadata | {"author":"cosmicstack-labs","version":"1.0.0","category":"frontend","tags":["nextjs","react","server-components","app-router","full-stack","ssr","ssg","isr"]} |
Comprehensive guide to building production-grade Next.js applications with the App Router, Server Components, and modern React patterns.
| Aspect | App Router | Pages Router |
|---|---|---|
| Components | Server Components by default | Client Components only |
| Routing | File-system based with layout nesting | File-system based, flat |
| Data Fetching | Server-side fetch, use, cache primitives | getServerSideProps, getStaticProps |
| Loading States | loading.js files | Manual implementation |
| Error Handling | error.js files | Manual implementation |
| Streaming | Built-in with Suspense boundaries | Not supported |
my-app/
├── app/
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Home page
│ ├── loading.tsx # Root loading state
│ ├── error.tsx # Root error boundary
│ ├── not-found.tsx # 404 page
│ ├── (auth)/ # Route group
│ │ ├── login/page.tsx
│ │ └── register/page.tsx
│ ├── dashboard/
│ │ ├── layout.tsx # Dashboard layout
│ │ ├── page.tsx # Dashboard home
│ │ ├── loading.tsx
│ │ └── settings/
│ │ └── page.tsx
│ └── api/
│ └── [...route]/route.ts # API handlers
├── components/
│ ├── ui/ # Shared UI components
│ └── features/ # Feature-specific components
├── lib/
│ ├── db.ts # Database client
│ ├── auth.ts # Auth utilities
│ └── utils.ts # Shared utilities
└── public/
└── images/
// ✅ SERVER COMPONENT (default) — Use for:
// - Data fetching from databases/APIs
// - Accessing backend resources directly
// - Keeping sensitive logic on server
// - Reducing client bundle size
// - SEO-critical content
async function ProductPage({ params }: { params: { id: string } }) {
const product = await db.product.findUnique({ where: { id: params.id } });
return <ProductDetail product={product} />;
}
// ✅ CLIENT COMPONENT — Use for:
// - Interactivity (onClick, onChange, etc.)
// - useState, useReducer, useEffect
// - Browser-only APIs
// - Custom hooks
// - Event listeners
'use client';
function AddToCartButton({ productId }: { productId: string }) {
const [added, setAdded] = useState(false);
return (
<button onClick={() => { addToCart(productId); setAdded(true); }}>
{added ? 'Added!' : 'Add to Cart'}
</button>
);
}
// ✅ CORRECT: Server Component wrapping Client Component
async function ProductPage({ id }: { id: string }) {
const product = await getProduct(id);
// Server component passes data as props to client component
return (
<div>
<ProductDetails product={product} />
<AddToCartButton productId={id} />
</div>
);
}
// ❌ WRONG: Client Component importing Server Component
'use client';
import ServerComponent from './ServerComponent'; // ❌ Won't work
function ClientPage() {
return <ServerComponent />; // Error: Cannot import server component into client
}
// ✅ CORRECT: Pass Server Component as children
'use client';
function ClientLayout({ children }: { children: React.ReactNode }) {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onClick={() => setIsOpen(!isOpen)}>Toggle</button>
{isOpen && children} {/* Server component rendered here */}
</div>
);
}
// app/products/page.tsx
async function ProductsPage() {
// Direct database access — no API route needed
const products = await db.product.findMany({
take: 20,
orderBy: { createdAt: 'desc' },
});
return <ProductGrid products={products} />;
}
// With parallel fetching for multiple data sources
async function DashboardPage() {
const [user, posts, analytics] = await Promise.all([
getCurrentUser(),
getRecentPosts(),
getAnalytics(),
]);
return (
<DashboardShell user={user}>
<PostList posts={posts} />
<AnalyticsChart data={analytics} />
</DashboardShell>
);
}
// Time-based revalidation (ISR)
export const revalidate = 3600; // Revalidate every hour
// On-demand revalidation (revalidateTag / revalidatePath)
'use server';
export async function publishPost(formData: FormData) {
const post = await createPost(formData);
revalidateTag('posts');
revalidatePath('/blog');
redirect(`/blog/${post.slug}`);
}
// Dynamic data — no caching
export const dynamic = 'force-dynamic';
// Static data — cache forever
export const dynamic = 'force-static';
// app/dashboard/page.tsx
import { Suspense } from 'react';
export default function DashboardPage() {
return (
<div>
<h1>Dashboard</h1>
<Suspense fallback={<DashboardSkeleton />}>
<DashboardContent />
</Suspense>
<Suspense fallback={<ActivitySkeleton />}>
<RecentActivity />
</Suspense>
</div>
);
}
async function DashboardContent() {
const data = await fetchDashboardData(); // This suspends
return <DashboardCharts data={data} />;
}
async function RecentActivity() {
const activity = await fetchRecentActivity(); // This loads independently
return <ActivityFeed items={activity} />;
}
// app/api/products/route.ts
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const page = parseInt(searchParams.get('page') || '1');
const limit = parseInt(searchParams.get('limit') || '20');
const products = await db.product.findMany({
skip: (page - 1) * limit,
take: limit,
});
return Response.json({ products, page, limit });
}
export async function POST(request: Request) {
const body = await request.json();
const product = await db.product.create({ data: body });
return Response.json(product, { status: 201 });
}
// app/(marketing)/page.tsx — Public marketing pages
// app/(dashboard)/page.tsx — Authenticated dashboard
// app/(auth)/login/page.tsx — Auth pages with different layout
// middleware.ts
export function middleware(request: NextRequest) {
const token = request.cookies.get('session');
const { pathname } = request.nextUrl;
// Protected routes
if (pathname.startsWith('/dashboard') && !token) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
// app/dashboard/error.tsx
'use client';
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
return (
<div>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</button>
</div>
);
}
'use client' when you need interactivity.Promise.all() for independent data fetches.no-store or revalidate explicitly.