Next.js 14 hadir dengan fitur App Router yang revolusioner serta Server Actions untuk mengoptimalkan performa. Ikuti tutorial step‑by‑step ini untuk membangun aplikasi full‑stack modern menggunakan Typescript, Docker, dan best practice keamanan.
1. Persiapan Lingkungan
Pastikan Anda memiliki Node.js 20.x atau lebih baru, npm 10 (atau yarn 4), serta Docker Desktop terinstal. Verifikasi dengan:
node -v
npm -v
docker --version
1.1. Membuat Direktori Proyek
mkdir nextjs14-app && cd nextjs14-app
1.2. Inisialisasi Project dengan Create‑Next‑App
npx create-next-app@latest . \ --ts \ --app \ --eslint \ --src-dir \ --import-alias "@/*"
Opsi --app mengaktifkan App Router secara default.
2. Struktur Direktori Baru (src)
src/ ├─ app/ # App Router (pages) │ ├─ layout.tsx # Root layout │ ├─ page.tsx # Home page │ └─ (dashboard)/ # Nested route contoh │ ├─ layout.tsx │ └─ page.tsx ├─ components/ # Komponen UI reusable ├─ lib/ # Helper, API client ├─ public/ # Asset statis └─ styles/ # CSS/SCSS
3. Instalasi Dependency Tambahan
npm i prisma @prisma/client \ next-auth \ tailwindcss postcss autoprefixer \ class-variance-authority clsx \ zod npx tailwindcss init -p
Konfigurasi tailwind.config.js untuk mode JIT dan path ke src/app:
module.exports = {
content: ["./src/**/*.{js,ts,jsx,tsx}"] ,
theme: { extend: {} },
plugins: [],
};
4. Setup Database dengan Prisma
4.1. Inisialisasi Prisma
npx prisma init --datasource-provider postgresql
Edit .env:
DATABASE_URL="postgresql://postgres:password@localhost:5432/next14db?schema=public"
4.2. Definisikan Model
model User {
id String @id @default(cuid())
email String @unique
name String?
password String // hashed via bcrypt
createdAt DateTime @default(now())
}
4.3. Migrasi
npx prisma migrate dev --name init
5. Implementasi Server Actions (Next.js 14)
Server Actions memungkinkan Anda menulis fungsi async di server yang dipanggil langsung dari komponen client.
5.1. Buat Action untuk Registrasi
/* src/app/(auth)/register/action.ts */
"use server";
import { prisma } from "@/lib/prisma";
import { hash } from "bcryptjs";
import { redirect } from "next/navigation";
import { z } from "zod";
const schema = z.object({
email: z.string().email(),
name: z.string().min(2),
password: z.string().min(8),
});
export async function registerAction(formData: FormData) {
const result = schema.safeParse({
email: formData.get("email"),
name: formData.get("name"),
password: formData.get("password"),
});
if (!result.success) throw new Error("Invalid input");
const { email, name, password } = result.data;
const hashed = await hash(password, 12);
await prisma.user.create({ data: { email, name, password: hashed } });
redirect("/login");
}
5.2. Konsumsi Action di Komponen Client
/* src/app/(auth)/register/page.tsx */
"use client";
import { registerAction } from "./action";
export default function RegisterPage() {
return (
);
}
6. Konfigurasi Authentication dengan Next‑Auth
6.1. Buat API Route
/* src/app/api/auth/[...nextauth]/route.ts */
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import { prisma } from "@/lib/prisma";
import { compare } from "bcryptjs";
export const authOptions = {
providers: [
CredentialsProvider({
name: "Credentials",
credentials: { email: { label: "Email", type: "text" }, password: { label: "Password", type: "password" } },
async authorize(credentials) {
const user = await prisma.user.findUnique({ where: { email: credentials?.email } });
if (user && (await compare(credentials!.password, user.password))) {
return { id: user.id, email: user.email, name: user.name };
}
return null;
},
}),
],
session: { strategy: "jwt" },
secret: process.env.NEXTAUTH_SECRET,
};
export const GET = async (req: Request) => NextAuth(req, authOptions);
export const POST = async (req: Request) => NextAuth(req, authOptions);
6.2. Proteksi Route Dashboard
/* src/app/(dashboard)/layout.tsx */
import { auth } from "@/lib/auth";
import { redirect } from "next/navigation";
export default async function DashboardLayout({ children }: { children: React.ReactNode }) {
const session = await auth();
if (!session) redirect("/login");
return ({children} );
}
7. Dockerisasi Aplikasi
7.1. Dockerfile
# syntax=docker/dockerfile:1 FROM node:20-alpine AS builder WORKDIR /app COPY package*.json . RUN npm ci COPY . . RUN npm run build FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production COPY --from=builder /app/.next ./.next COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/public ./public COPY --from=builder /app/package*.json ./ EXPOSE 3000 CMD ["npm", "start"]
7.2. docker-compose.yml
version: "3.9"
services:
web:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://postgres:password@db:5432/next14db?schema=public
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
depends_on:
- db
db:
image: postgis/postgis:15-3.4
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: next14db
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
8. Best Practice & Security
- Environment Variables: Gunakan
.env.localuntuk dev dan secret manager (AWS SSM, GCP Secret Manager) di prod. - Input Validation: Selalu validasi dengan
zodatauyupdi server actions. - Rate Limiting: Tambahkan middleware
next-rate-limitpada API routes untuk mencegah brute‑force. - HTTP Headers: Pakai
helmetvia custom server ataunext-secure-headersuntuk CSP, HSTS, dll. - CSRF Protection: Next‑Auth sudah melindungi token, tapi untuk action custom gunakan
csrftoken di form. - Logging & Monitoring: Integrasikan dengan
pinodanGrafana Lokilewat sidecar Docker.
9. Deployment ke Vercel (Opsional)
- Push repository ke GitHub.
- Di Vercel, pilih Import Project, sambungkan repository.
- Set environment variables:
DATABASE_URL,NEXTAUTH_SECRET. - Vercel otomatis mengenali
next.config.jsdan melakukan build.
10. Testing Dasar
npm i -D jest @testing-library/react @testing-library/jest-dom ts-jest npx jest --init
Contoh test komponen RegisterPage:
import { render, screen } from "@testing-library/react";
import RegisterPage from "@/app/(auth)/register/page";
test("renders registration form", () => {
render( );
expect(screen.getByPlaceholderText(/email/i)).toBeInTheDocument();
expect(screen.getByPlaceholderText(/password/i)).toBeInTheDocument();
});
Dengan mengikuti tutorial ini Anda memiliki aplikasi Next.js 14 yang sepenuhnya modern: App Router, Server Actions, TypeScript, Prisma ORM, autentikasi berbasis credential, serta Docker untuk lingkungan produksi yang konsisten. Terapkan best practice keamanan, testing, dan CI/CD untuk menjamin kualitas kode. Selamat mengembangkan!
Panduan lengkap setup Next.js 14 dengan App Router, Server Actions, Typescript, Prisma, Docker, serta best practice keamanan dan deployment.
Programming,Software Engineering,Web Development
#Programming #SoftwareEngineering #WebDev #Tech #Coding
0 Komentar