Panduan Lengkap Setup Next.js 14 dengan App Router, TypeScript, dan Prisma di 2026


Artikel ini memberikan tutorial step‑by‑step untuk menyiapkan proyek Next.js 14 terbaru dengan TypeScript, App Router, Prisma ORM, dan deployment ke Vercel, lengkap dengan konfigurasi, contoh kode, dan best practice modern.

1. Prasyarat dan Persiapan Lingkungan

Pastikan Anda memiliki perangkat lunak berikut terinstal pada mesin pengembangan:

  • Node.js v20.10 atau lebih baru (download)
  • npm v10+ atau Yarn v4 (Berry)
  • Git
  • Dashboard Vercel (opsional untuk deployment)

Verifikasi instalasi dengan perintah:

node -v
npm -v

2. Membuat Proyek Next.js 14 Baru

Gunakan create-next-app dengan template TypeScript dan App Router:

npx create-next-app@latest my-next14-app \
  --ts \
  --app
cd my-next14-app

Struktur folder utama akan terlihat seperti:

my-next14-app/
├─ app/               # App Router (pages dir deprecated)
├─ public/
├─ src/
│  └─ lib/            # Tempat menaruh Prisma client
├─ .env.local
└─ package.json

3. Instalasi Dependensi Utama

Tambahkan Prisma, PostgreSQL driver, dan library utilitas lain:

npm install prisma @prisma/client
npm install -D prisma@latest
npm install @vercel/postgres

Jika Anda menggunakan MySQL atau SQLite, ganti driver yang sesuai.

4. Inisialisasi Prisma dan Skema Database

Jalankan perintah berikut untuk membuat file schema.prisma:

npx prisma init --datasource-provider postgresql

File prisma/schema.prisma default akan berisi:

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

Tambahkan model contoh User dan Post:

model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  name      String?
  posts     Post[]
  createdAt DateTime @default(now())
}

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  authorId  Int
  author    User     @relation(fields: [authorId], references: [id])
  createdAt DateTime @default(now())
}

5. Menyiapkan Database di Vercel (atau Lokal)

Jika Anda memakai Vercel Postgres, buat proyek di dashboard Vercel → Add Integration → PostgreSQL. Salin connection string ke .env.local:

DATABASE_URL="postgresql://user:password@db.vercel-storage.com:5432/dbname"

Untuk pengembangan lokal, gunakan Docker:

docker run --name pg-dev -e POSTGRES_PASSWORD=secret -p 5432:5432 -d postgres:15
export DATABASE_URL="postgresql://postgres:secret@localhost:5432/postgres"

6. Migrasi Skema ke Database

Jalankan migrasi Prisma sehingga tabel dibuat:

npx prisma migrate dev --name init

Periksa hasil dengan:

npx prisma studio

7. Membuat Prisma Client Wrapper

Di folder src/lib, buat file prisma.ts yang menyiapkan singleton client (menghindari multiple instances di serverless):

import { PrismaClient } from "@prisma/client";

let prisma: PrismaClient;

if (process.env.NODE_ENV === "production") {
  prisma = new PrismaClient();
} else {
  // @ts-ignore – global di development hanya sekali
  if (!global.prisma) {
    global.prisma = new PrismaClient();
  }
  prisma = global.prisma;
}

export default prisma;

8. Membuat API Route dengan App Router

Di app/api/posts/route.ts (Next.js 14 menggunakan file route.ts), buat endpoint CRUD dasar:

import { NextResponse } from "next/server";
import prisma from "@/src/lib/prisma";

export async function GET() {
  const posts = await prisma.post.findMany({ include: { author: true } });
  return NextResponse.json(posts);
}

export async function POST(request: Request) {
  const { title, content, authorEmail } = await request.json();
  const author = await prisma.user.upsert({
    where: { email: authorEmail },
    update: {},
    create: { email: authorEmail, name: "Anonymous" },
  });
  const post = await prisma.post.create({
    data: { title, content, authorId: author.id },
  });
  return NextResponse.json(post, { status: 201 });
}

9. Membuat UI dengan Server Components

Di app/posts/page.tsx, tampilkan daftar postingan menggunakan Server Component:

import prisma from "@/src/lib/prisma";
import Link from "next/link";

export const dynamic = "force-dynamic"; // memastikan fresh data tiap request

export default async function PostsPage() {
  const posts = await prisma.post.findMany({
    include: { author: true },
    orderBy: { createdAt: "desc" },
  });

  return (
    <section>
      <h1 className="text-2xl font-bold mb-4">Blog Posts</h1>
      {posts.map((p) => (
        <article key={p.id} className="mb-6 p-4 border rounded">
          <h2 className="text-xl font-semibold">{p.title}</h2>
          <p className="text-gray-600">by {p.author.name || p.author.email}</p>
          <p>{p.content?.slice(0, 150)}...</p>
          <Link href={`/posts/${p.id}`} className="text-blue-500">Read more</Link>
        </article>
      ))}
      <Link href="/posts/new" className="inline-block mt-4 text-white bg-blue-600 px-4 py-2 rounded">Create New Post</Link>
    </section>
  );
}

10. Formulir Pembuatan Post (Client Component)

Di app/posts/new/page.tsx, gunakan React Hook Form dan fetch API:

"use client";
import { useState } from "react";

export default function NewPost() {
  const [title, setTitle] = useState("");
  const [content, setContent] = useState("");
  const [email, setEmail] = useState("");

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    const res = await fetch("/api/posts", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ title, content, authorEmail: email }),
    });
    if (res.ok) {
      // redirect atau reset form
      window.location.href = "/posts";
    } else {
      alert("Failed to create post");
    }
  };

  return (
    <form onSubmit={handleSubmit} className="max-w-lg mx-auto">
      <h1 className="text-2xl mb-4">Create New Post</h1>
      <label className="block mb-2">Email:
        <input type="email" value={email} onChange={e=>setEmail(e.target.value)} required className="w-full border p-2" />
      </label>
      <label className="block mb-2">Title:
        <input type="text" value={title} onChange={e=>setTitle(e.target.value)} required className="w-full border p-2" />
      </label>
      <label className="block mb-2">Content:
        <textarea value={content} onChange={e=>setContent(e.target.value)} rows={6} className="w-full border p-2" />
      </label>
      <button type="submit" className="mt-4 bg-green-600 text-white px-4 py-2 rounded">Publish</button>
    </form>
  );
}

11. Menambahkan Security Best Practice

  • Rate limiting: Instal next-rate-limit dan gunakan middleware untuk endpoint API.
  • Input sanitization: Gunakan library zod untuk validasi schema sebelum menyimpan ke DB.
  • CORS: Karena Next.js API berada di domain yang sama, biasanya tidak diperlukan, tetapi jika Anda memanggil dari sub‑domain, set Access-Control-Allow-Origin di middleware.
  • HTTP security headers: Tambahkan next-secure-headers dalam next.config.js.

12. Optimasi Performa

Beberapa langkah yang terbukti menurunkan TTFB di produksi:

  • Gunakan incremental static regeneration (ISR) untuk halaman yang tidak berubah tiap request. Contoh: export const revalidate = 60; pada app/posts/page.tsx.
  • Cache result Prisma dengan unstable_cache (Next.js 14 experimental) bila data jarang berubah.
  • Aktifkan gambar optimizer bawaan Next.js (next/image) untuk media dalam konten.

13. Deploy ke Vercel

Langkah paling cepat:

  1. Push repo ke GitHub.
  2. Buka dashboard Vercel → New Project → pilih repo.
  3. Pastikan Environment Variable DATABASE_URL sudah diset.
  4. Deploy! Vercel secara otomatis menjalankan npm install && npm run build.

Setelah deploy, akses https://your-project.vercel.app/posts dan coba buat postingan baru.

14. Monitoring & Logging

Integrasikan Uptrace atau Logtail untuk tracing request dan query Prisma. Tambahkan middleware:

import { trace } from "@opentelemetry/api";
export async function middleware(request: NextRequest) {
  const span = trace.getTracer("nextjs").startSpan("request" );
  // ...do work
  span.end();
  return NextResponse.next();
}

15. Tips Tambahan & Pitfalls Umum

  • Never commit .env files. Gunakan .gitignore dan rahasiakan kredensial di Vercel.
  • Prisma Client dalam Serverless: Pastikan singleton pattern (lihat step 7) untuk menghindari koneksi DB yang terombak.
  • TypeScript strict mode: Aktifkan strict: true di tsconfig.json untuk deteksi bug lebih awal.
  • Testing: Gunakan jest + @testing-library/react untuk unit UI, dan prisma-test-utils untuk integration test DB.

Dengan mengikuti langkah‑langkah di atas, Anda dapat membangun aplikasi full‑stack modern menggunakan Next.js 14, TypeScript, dan Prisma, sekaligus menerapkan best practice keamanan, performa, dan deployment ke Vercel. Kombinasi ini menjadi standar industri pada 2026 untuk proyek web berkecepatan tinggi dan mudah dipelihara, memberikan fondasi yang kuat bagi pengembangan lanjutan seperti ISR, Edge Functions, atau integrasi AI. Selamat mencoba, dan jangan ragu untuk bereksperimen dengan fitur-fitur baru App Router seperti loading.tsx atau error.tsx untuk pengalaman pengguna yang lebih halus.
Tutorial lengkap 2026 tentang cara setup Next.js 14 dengan TypeScript, App Router, Prisma, dan deployment ke Vercel. Termasuk instalasi, konfigurasi, contoh kode, security, dan performance best practice.

Programming,Software Engineering,Web Development

#Programming #SoftwareEngineering #WebDev #Tech #Coding

Posting Komentar

0 Komentar