com um clique
backend-api
Build server-side APIs using Next.js Server Actions and API routes.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Menu
Build server-side APIs using Next.js Server Actions and API routes.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Baseado na classificação ocupacional SOC
Build accessible portfolio websites following WCAG guidelines with proper semantics, keyboard navigation, screen reader support, and inclusive design patterns.
Implement analytics, error monitoring, and performance tracking with Vercel Analytics, Google Analytics, Sentry, and custom event tracking.
Build production-ready contact forms with React Hook Form, Zod validation, Server Actions, and email services like Resend.
Manage portfolio content with MDX, Contentlayer, or local JSON for projects, blog posts, and dynamic content.
Implement robust dark mode and theming systems with next-themes, CSS custom properties, and Tailwind CSS for seamless user experience.
Deploy applications to production using Vercel CLI commands.
| name | backend-api |
| description | Build server-side APIs using Next.js Server Actions and API routes. |
| author | Jaivish Chauhan @ GDG SSIT |
| version | 1.0.0 |
| url | https://github.com/JaivishChauhan/vibecoding-starter |
In the Modern Web (Next.js App Router), the line between frontend and backend is blurred but strict. Code co-location is key, but security boundaries are paramount. We prefer Server Actions for mutations and Server Components for data fetching.
By default, everything in app/ is a Server Component.
| Feature | Server Component (Default) | Client Component ('use client') |
|---|---|---|
| Data Fetching | ✅ Direct DB / API calls (async/await) | ❌ Must use useEffect / SWR / React Query |
| Secrets | ✅ Can access env vars (API_KEY) | ❌ Exposure risk |
| Interactivity | ❌ No onClick, onChange, hooks | ✅ Full React interactivity |
| Bundle Size | ✅ Zero bundle size impact | ❌ Adds to client JS bundle |
Best Practice: Keep the "Client Boundary" as low in the tree as possible. Pass Server Components as children to Client Components to prevent them from becoming Client Components themselves.
Fetch data directly in your async Page or Layout components.
// app/dashboard/page.jsx
import { db } from "@/lib/db";
export default async function DashboardPage() {
// Direct DB call - safe on server
const users = await db.user.findMany();
return (
<main>
<h1>Users</h1>
<UserList users={users} />
</main>
);
}
Server Actions are the standard way to handle form submissions and data mutations.
Always validate inputs on the server using Zod. Never trust the client.
// actions/create-post.ts
'use server'
import { z } from "zod";
import { db } from "@/lib/db";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
const schema = z.object({
title: z.string().min(5),
content: z.string().min(10)
});
export async function createPost(prevState: any, formData: FormData) {
const validatedFields = schema.safeParse({
title: formData.get('title'),
content: formData.get('content')
});
if (!validatedFields.success) {
return {
errors: validatedFields.error.flatten().fieldErrors,
message: 'Missing Fields. Failed to Create Post.',
};
}
try {
await db.post.create({
data: validatedFields.data,
});
} catch (error) {
return { message: 'Database Error: Failed to Create Post.' };
}
revalidatePath('/dashboard/posts');
redirect('/dashboard/posts');
}
Use useFormState (or useActionState in React 19) to handle feedback.
// components/post-form.jsx
"use client";
import { useFormState } from "react-dom";
import { createPost } from "@/actions/create-post";
export function PostForm() {
const [state, dispatch] = useFormState(createPost, {
message: null,
errors: {},
});
return (
<form action={dispatch}>
<input name="title" />
{state.errors?.title && (
<p className="text-red-500">{state.errors.title}</p>
)}
<button type="submit">Save</button>
<p aria-live="polite">{state.message}</p>
</form>
);
}
Use Route Handlers (app/api/.../route.js) when you need to expose endpoints to external services (webhooks, mobile apps, public API).
// app/api/webhooks/stripe/route.js
import { headers } from "next/headers";
import { NextResponse } from "next/server";
export async function POST(req) {
const body = await req.text();
const signature = headers().get("Stripe-Signature");
try {
// Verify webhook signature
// Process event
return NextResponse.json({ received: true });
} catch (err) {
return NextResponse.json({ error: "Webhook Error" }, { status: 400 });
}
}
In development, Next.js hot-reloading can exhaust database connections. Use a singleton pattern.
// lib/db.ts
import { PrismaClient } from "@prisma/client";
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
export const db = globalForPrisma.prisma || new PrismaClient();
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db;
unstable_cache: Cache expensive DB queries by key/tag.revalidateTag: Purge cache on demand (e.g., after an admin update).const session = await auth();
if (!session || session.user.role !== "ADMIN") {
throw new Error("Unauthorized");
}
NEXT_PUBLIC_ unless they are truly public.