Table of Contents
Open Table of Contents
Route Management
Dynamic Routes
Next.js mendukung dynamic routes untuk membuat halaman yang dinamis berdasarkan parameter. Misalnya, untuk menampilkan detail course berdasarkan id
.
Buat file pages/courses/[id].tsx
:
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
const CourseDetail = () => {
const router = useRouter();
const { id } = router.query;
const [course, setCourse] = useState(null);
useEffect(() => {
if (id) {
fetch(`/api/courses/${id}`)
.then(res => res.json())
.then(data => setCourse(data));
}
}, [id]);
if (!course) return <div>Loading...</div>;
return (
<div>
<h1>{course.title}</h1>
<p>{course.description}</p>
</div>
);
};
export default CourseDetail;
Protected Routes
Untuk melindungi route tertentu (misalnya, hanya admin yang bisa mengakses dashboard), kita bisa menggunakan middleware atau client-side protection.
Contoh middleware di pages/middleware.ts
:
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const role = request.cookies.get("role")?.value;
if (request.nextUrl.pathname.startsWith("/admin") && role !== "admin") {
return NextResponse.redirect(new URL("/login", request.url));
}
return NextResponse.next();
}
Zustand State Management
Setup Zustand
Install Zustand:
npm install zustand
Buat store untuk mengelola state global, misalnya untuk user dan course.
Buat file store/userStore.ts
:
import { create } from "zustand";
interface UserState {
user: { id: number; name: string; role: string } | null;
setUser: (user: { id: number; name: string; role: string }) => void;
clearUser: () => void;
}
export const useUserStore = create<UserState>(set => ({
user: null,
setUser: user => set({ user }),
clearUser: () => set({ user: null }),
}));
Global State untuk User dan Course
Contoh penggunaan Zustand di komponen:
import { useUserStore } from "../store/userStore";
const UserProfile = () => {
const user = useUserStore(state => state.user);
if (!user) return <div>Please login</div>;
return (
<div>
<h1>Welcome, {user.name}</h1>
<p>Role: {user.role}</p>
</div>
);
};
export default UserProfile;
Role-Based Access Control (RBAC)
Implementasi RBAC di API Routes
Tambahkan validasi role di API routes. Misalnya, hanya admin yang bisa menambahkan course.
Contoh di pages/api/courses/index.ts
:
import { NextApiRequest, NextApiResponse } from "next";
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const role = req.headers["role"];
if (req.method === "POST" && role !== "admin") {
return res.status(403).json({ message: "Forbidden" });
}
if (req.method === "POST") {
const { title, description } = req.body;
try {
const course = await prisma.course.create({
data: { title, description },
});
res.status(201).json(course);
} catch (error) {
res.status(500).json({ message: "Failed to add course" });
}
} else {
res.status(405).json({ message: "Method not allowed" });
}
}
Implementasi RBAC di Frontend
Gunakan Zustand untuk memeriksa role user sebelum mengakses halaman tertentu.
Contoh di pages/admin/dashboard.tsx
:
import { useUserStore } from "../../store/userStore";
import { useEffect } from "react";
import { useRouter } from "next/router";
const AdminDashboard = () => {
const user = useUserStore(state => state.user);
const router = useRouter();
useEffect(() => {
if (user?.role !== "admin") {
router.push("/login");
}
}, [user, router]);
if (!user || user.role !== "admin") return <div>Redirecting...</div>;
return (
<div>
<h1>Admin Dashboard</h1>
<p>Welcome, {user.name}</p>
</div>
);
};
export default AdminDashboard;
Optimasi
Code Splitting
Gunakan React.lazy
dan Suspense
untuk code splitting:
import { lazy, Suspense } from "react";
const LazyComponent = lazy(() => import("./LazyComponent"));
const Home = () => (
<div>
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
</div>
);
export default Home;
Caching dengan SWR
Install SWR untuk caching dan fetching data:
npm install swr
Contoh penggunaan SWR:
import useSWR from "swr";
const fetcher = (url: string) => fetch(url).then(res => res.json());
const CourseList = () => {
const { data, error } = useSWR("/api/courses", fetcher);
if (error) return <div>Failed to load</div>;
if (!data) return <div>Loading...</div>;
return (
<ul>
{data.map(course => (
<li key={course.id}>{course.title}</li>
))}
</ul>
);
};
export default CourseList;
Prisma Query Optimization
Optimasi query Prisma dengan menggunakan select
dan include
secara bijak:
const courses = await prisma.course.findMany({
select: {
id: true,
title: true,
materials: {
select: {
title: true,
},
},
},
});
Kesimpulan
Dengan menerapkan route management, Zustand state management, role-based access control, dan optimasi, platform e-learning Anda akan lebih terstruktur, aman, dan efisien. Selamat mencoba!