Next.js 14 menjadi standar de‑facto untuk pengembangan aplikasi React modern. Tutorial ini mengajarkan cara menginstal, mengonfigurasi, menulis kode, dan menerapkan best practice agar aplikasi siap produksi di 2026.

1. Prasyarat & Persiapan Lingkungan

Sebelum memulai, pastikan Anda memiliki:

  • Node.js v20.10 atau lebih baru (unduh di nodejs.org)
  • npm v10 atau Yarn v4 (pilih salah satu)
  • Git untuk version control
  • Editor kode modern, misalnya VS Code dengan ekstensi ESLint dan Prettier

Jika menggunakan Docker, pastikan Docker Desktop versi 4.30+ ter‑install.

2. Membuat Project Next.js 14 Baru

npx create-next-app@latest my-next14-app --example "https://github.com/vercel/next.js/tree/canary/examples/with-tailwindcss" --typescript
cd my-next14-app

Perintah di atas membuat aplikasi starter dengan TypeScript, Tailwind CSS, dan konfigurasi linting standar.

3. Mengaktifkan App Router

Next.js 14 mempromosikan App Router sebagai default. Pastikan struktur folder app/ ada di root proyek. Jika masih ada pages/, Anda dapat menonaktifkannya dengan menambah file next.config.js berikut:

module.exports = {
  // Memaksa penggunaan app router
  experimental: { appDir: true },
  reactStrictMode: true,
  images: { remotePatterns: [{ protocol: 'https', hostname: '**' }] },
};

Setelah itu, hapus atau rename folder pages menjadi pages_old untuk menghindari konflik.

4. Menyiapkan Server Actions (Beta Stabil)

Server Actions memungkinkan Anda menulis fungsi yang dijalankan di server langsung dari komponen React, tanpa API route terpisah.

// app/api/actions.ts
'use server';
import { prisma } from '@/lib/prisma';

export async function createPost(data: { title: string; content: string }) {
  'use server';
  const post = await prisma.post.create({ data });
  return post;
}

Import fungsi ini di komponen client:

// app/dashboard/page.tsx
'use client';
import { useState } from 'react';
import { createPost } from '@/app/api/actions';

export default function Dashboard() {
  const [title, setTitle] = useState('');
  const [content, setContent] = useState('');

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    const post = await createPost({ title, content });
    alert(`Post created: ${post.id}`);
  };

  return (
    
setTitle(e.target.value)} placeholder="Title" className="input" />