Next.js 14 menjadi standar baru untuk pengembangan aplikasi React full‑stack. Artikel ini membahas langkah demi langkah menginstal, mengonfigurasi, menulis kode, serta best practice untuk keamanan dan performa, lengkap dengan contoh nyata yang siap diproduksi.
1. Prasyarat dan Persiapan Lingkungan
Pastikan Anda memiliki perangkat lunak berikut terpasang:
- Node.js v20.10+ (LTS)
- npm 9.10+ atau
pnpm(disarankan) - Git untuk kontrol versi
- Editor kode modern, contoh Visual Studio Code dengan ekstensi ESLint dan Prettier
Jika belum terpasang, instal Node.js dari nodejs.org dan ikuti instruksi instalasi pnpm:
npm install -g pnpm
2. Membuat Proyek Next.js 14 Baru
pnpm create next-app@latest my-next14-app --ts
Perintah di atas memulai wizard interaktif. Pilih opsi:
- App Router (default pada Next.js 14)
- Tailwind CSS untuk styling cepat
- ESLint + Prettier untuk code quality
Setelah selesai, masuk ke folder proyek:
cd my-next14-app
Jalankan development server untuk memastikan semuanya berfungsi:
pnpm dev
Buka http://localhost:3000 di browser. Anda harus melihat halaman landing default Next.js.
3. Struktur Direktori Baru dengan App Router
Next.js 14 menggantikan pages/ dengan app/. Berikut struktur penting:
app/
├─ layout.tsx # Root layout, berisi &
├─ page.tsx # Halaman beranda
├─ dashboard/
│ ├─ layout.tsx # Layout khusus dashboard
│ └─ page.tsx # Konten dashboard
└─ api/
└─ hello/route.ts # API route dengan Server Action
Struktur ini mendukung rendering sisi server (SSR), statis (SSG), dan server actions secara native.
4. Mengonfigurasi Tailwind CSS (Opsional but Recommended)
Jika Anda memilih Tailwind pada langkah 2, file konfigurasinya sudah ada. Pastikan tailwind.config.ts mengaktifkan content untuk folder app:
content: ["./app/**/*.{js,ts,jsx,tsx}"]
Jika tidak, tambahkan secara manual, lalu jalankan:
pnpm dev
Gunakan kelas Tailwind di komponen:
<h1 className="text-4xl font-bold text-center">Selamat Datang</h1>
5. Membuat Server Action sederhana
Server Actions memungkinkan Anda menulis fungsi yang dijalankan di server tanpa membuat API terpisah. Buat file app/contact/action.ts:
"use server";
import { revalidatePath } from "next/cache";
export async function submitContact(formData: FormData) {
const name = formData.get("name") as string;
const email = formData.get("email") as string;
const message = formData.get("message") as string;
// Simulasi penyimpanan ke DB (misal Prisma)
// await prisma.contact.create({ data: { name, email, message } });
// Revalidasi halaman beranda setelah pengiriman
revalidatePath("/");
return { success: true };
}
Selanjutnya, buat halaman form di app/contact/page.tsx:
import { submitContact } from "./action";
export default function ContactPage() {
return (
<form action={submitContact} className="max-w-md mx-auto p-4">
<label className="block mb-2">Nama:<input name="name" required className="w-full border rounded"/></label>
<label className="block mb-2">Email:<input name="email" type="email" required className="w-full border rounded"/></label>
<label className="block mb-2">Pesan:<textarea name="message" required className="w-full border rounded"/></label>
<button type="submit" className="bg-blue-600 text-white px-4 py-2 rounded">Kirim</button>
</form>
);
}
Catatan: "use server" menandai fungsi agar hanya dijalankan di server, menghilangkan kebutuhan API endpoint terpisah.
6. Menambahkan Prisma ORM dan PostgreSQL
Untuk contoh produksi, gunakan PostgreSQL di cloud (Neon, Supabase, atau AWS RDS). Instal dependensi:
pnpm add prisma @prisma/client
pnpm prisma init
Ubah prisma/schema.prisma:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model Contact {
id Int @id @default(autoincrement())
name String
email String @unique
message String
createdAt DateTime @default(now())
}
Jalankan migrasi:
pnpm prisma migrate dev --name init
Setelah itu, impor client di action.ts dan simpan data nyata:
import { prisma } from "@/lib/prisma";
export async function submitContact(formData: FormData) {
const name = formData.get("name") as string;
const email = formData.get("email") as string;
const message = formData.get("message") as string;
await prisma.contact.create({ data: { name, email, message } });
revalidatePath("/");
return { success: true };
}
Buat file helper lib/prisma.ts:
import { PrismaClient } from "@prisma/client";
export const prisma = new PrismaClient();
7. Optimasi Performans – Image & Font
Next.js 14 menyediakan next/image yang di‑optimalkan secara otomatis. Ganti tag <img> dengan:
import Image from "next/image";
<Image src="/hero.jpg" alt="Hero" width={1200} height={600} priority />
Gunakan next/font untuk loading font lokal atau Google Fonts tanpa FOUT:
import { Inter } from "next/font/google";
const inter = Inter({ subsets: ["latin"] });
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className={inter.className}>
<body>{children}</body>
</html>
);
}
8. Keamanan – CSRF, Rate Limiting, dan HTTP Headers
- CSRF: Server Actions otomatis menolak request tanpa token yang valid, tapi untuk API custom tambahkan
csrfmiddleware (misalnext-safe-middleware). - Rate Limiting: Pasang
rate-limitpada route API diapp/api/…/route.ts.import rateLimit from "@upstash/rate-limit"; const limiter = rateLimit({ redis: redisInstance, limiter: Ratelimit.fixedWindow(10, "1 m") }); export async function GET(request: Request) { const ip = request.headers.get("x-forwarded-for") ?? "unknown"; const { success } = await limiter.limit(ip); if (!success) return new Response("Too Many Requests", { status: 429 }); return new Response("OK"); } - Security Headers: Tambahkan
next-secure-headersdinext.config.mjs.import { createSecureHeaders } from "next-secure-headers"; export default defineConfig({ async headers() { return [{ source: "/(.*)", headers: createSecureHeaders({ contentSecurityPolicy: { directives: { defaultSrc: "'self'", scriptSrc: ["'self'", "'unsafe-inline'"], styleSrc: ["'self'", "'unsafe-inline'"], }, }, referrerPolicy: "strict-origin-when-cross-origin", }) }]; } });
9. Deploy ke Vercel (Zero‑Config) dan Alternatif Cloudflare Pages
Vercel tetap platform paling mudah untuk Next.js 14. Ikuti langkah:
- Push repo ke GitHub.
- Buka Vercel Dashboard → New Project → pilih repo.
- Pastikan
Build Command=pnpm builddanOutput Directory=.next. - Tambahkan environment variable
DATABASE_URLpada Settings → Environment Variables. - Deploy dan tunggu proses selesai.
Jika memilih Cloudflare Pages dengan @cloudflare/next-on-pages, instal adapter:
pnpm add @cloudflare/next-on-pages
Kemudian, di next.config.mjs:
export default defineConfig({
output: "standalone",
images: { unoptimized: true },
experimental: { appDir: true },
});
Build lokal, upload .output ke Cloudflare melalui CLI.
10. Best Practice untuk Produksi
- TypeScript strict mode: pastikan
"strict": trueditsconfig.jsonuntuk mengurangi bug. - Linting & Formatting: gunakan
eslint-config-nextdanprettierdengan script"lint": "next lint && prettier --check .". - Monitoring: integrasikan dengan Vercel Analytics atau gunakan
Sentryuntuk error tracking. - Incremental Static Regeneration (ISR): pada halaman yang membutuhkan update periodik, gunakan
revalidatedifetch.export const revalidate = 60; // tiap menit
11. Testing – Unit, Integration, End‑to‑End
Instal Jest, React Testing Library, dan Playwright:
pnpm add -D jest @testing-library/react @testing-library/jest-dom playwright
Contoh unit test untuk komponen Button:
import { render, screen } from "@testing-library/react";
import Button from "@/components/Button";
test("renders button with label", () => {
render(<Button>Click Me</Button>);
expect(screen.getByRole("button", { name: /click me/i })).toBeInTheDocument();
});
Playwright untuk E2E:
import { test, expect } from "@playwright/test";
test("contact form submission", async ({ page }) => {
await page.goto("/contact");
await page.fill("input[name=name]", "Budi");
await page.fill("input[name=email]", "budi@example.com");
await page.fill("textarea[name=message]", "Halo!");
await page.click("button:text('Kirim')");
await expect(page).toHaveURL(/\/thank-you/);
});
12. Upgrade ke Next.js 15 (Beta) – Apa yang Perlu Diketahui?
Next.js 15 masih dalam fase beta (Juni 2026). Jika ingin menguji, cukup ubah versi di package.json:
"next": "15.0.0-beta.3"
Catatan: beberapa API seperti next/font diganti dengan next/optimized-fonts. Ikuti dokumen resmi beta untuk migrasi bertahap.
13. Penutup – Checklist Sebelum Launch
- Run
pnpm lint && pnpm testtanpa error. - Audit bundle dengan
pnpm next build && pnpm next analyse. - Pastikan semua env var (DATABASE_URL, NEXT_PUBLIC_*) terisi di production.
- Aktifkan
Redirects & Rewritesdi Vercel untuk SEO friendly URLs. - Set up monitoring (Sentry) & alert Slack.
Dengan mengikuti tutorial ini, Anda memiliki stack modern yang siap skala, aman, dan performa tinggi.
Next.js 14 membawa paradigma baru dengan App Router dan Server Actions, memudahkan developer membangun aplikasi full‑stack tanpa boilerplate berlebih. Dengan mengikuti langkah instalasi, konfigurasi Prisma, optimasi performa, serta best practice keamanan, Anda dapat merilis produk yang stabil, mudah dipelihara, dan siap bersaing di pasar modern. Jangan lupa terus ikuti update roadmap Next.js untuk memanfaatkan fitur-fitur eksperimental seperti Edge Runtime dan AI‑native components di versi mendatang.
Tutorial lengkap setup Next.js 14 dengan App Router, Server Actions, Prisma, keamanan, dan deployment ke Vercel. Panduan step‑by‑step untuk developer modern.
Programming,Software Engineering,Web Development,Next.js,React,Full Stack,Server Actions,Prisma
#Programming #SoftwareEngineering #WebDev #Tech #Coding
0 Komentar