Next.js 14 menjadi standar baru untuk aplikasi React full‑stack. Tutorial ini menuntun Anda dari instalasi hingga deployment production, lengkap dengan contoh kode, konfigurasi, dan best practice terkini (2026).

1. Persiapan Lingkungan

Pastikan Anda memiliki Node.js 20.x+ dan npm 10+ atau pnpm 9+. Versi LTS terbaru memberikan dukungan built‑in fetch, edge runtime, dan mempercepat instalasi paket.

node -v
npm -v   # atau pnpm -v

Jika belum terpasang, unduh dari nodejs.org atau gunakan manager seperti nvm:

nvm install 20
nvm use 20

2. Membuat Proyek Next.js 14

Gunakan create-next-app dengan flag --experimental-app (meski di 14 fitur App Router sudah stabil, flag memastikan struktur terbaru).

npx create-next-app@latest my-next14-app --ts --eslint --src-dir --app-dir

Perintah di atas menghasilkan:

  • Folder src/app sebagai root App Router.
  • TypeScript dan ESLint pre‑configured.
  • Struktur src/pages tidak lagi dipakai, menghindari konflik.

3. Menjalankan Development Server

cd my-next14-app
npm run dev   # atau pnpm dev

Akses http://localhost:3000. Anda akan melihat halaman starter yang sudah menggunakan app/layout.tsx dan app/page.tsx.

4. Konfigurasi Dasar

4.1 next.config.js

Buka next.config.mjs (atau .js) dan tambahkan opsi penting untuk produksi 2026:

import { defineConfig } from 'next';

export default defineConfig({
  reactStrictMode: true,
  swcMinify: true,
  experimental: {
    serverActions: true, // enable Server Actions API
    serverComponentsExternalPackages: ['@prisma/client']
  },
  images: {
    remotePatterns: [{ protocol: 'https', hostname: '**' }]
  },
  i18n: {
    locales: ['en', 'id'],
    defaultLocale: 'en'
  }
});

4.2 .env.local

Tambahkan variabel rahasia, contohnya koneksi Prisma ke PostgreSQL:

DATABASE_URL=postgresql://user:password@localhost:5432/mydb

Gunakan next/config untuk mengaksesnya secara server‑only.

5. Membuat Server Action untuk CRUD

Server Actions memungkinkan Anda menulis fungsi asynchronous yang dijalankan di server tanpa API route terpisah.

5.1 Buat Model Prisma

// prisma/schema.prisma
model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  createdAt DateTime @default(now())
}

Jalankan migrasi:

npx prisma migrate dev --name init

5.2 Implementasi Server Action

Buat file src/app/posts/create-action.ts:

"use server";
import { prisma } from '@/lib/prisma';

export async function createPost(formData: FormData) {
  const title = formData.get('title')?.toString() ?? '';
  const content = formData.get('content')?.toString() ?? '';
  if (!title) throw new Error('Title is required');
  await prisma.post.create({ data: { title, content } });
  // Next.js 14 will automatically revalidate the page if you use
  // `revalidatePath` from "next/cache" (optional)
}

5.3 Form di Client Component

Di src/app/posts/page.tsx (Client Component karena ada interaksi UI):

"use client";
import { useState } from 'react';
import { createPost } from './create-action';

export default function PostsPage() {
  const [error, setError] = useState('');
  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    const formData = new FormData(e.target as HTMLFormElement);
    try {
      await createPost(formData);
      // optional: refresh UI with mutate or revalidatePath
    } catch (err: any) {
      setError(err.message);
    }
  };

  return (
    

Create Post

{error &&

{error}

}