Struktur Folder Best Practice untuk Next.js App Router
Dokumentasi ini menjelaskan struktur folder yang umum dipakai di industri untuk project Next.js App Router, termasuk penempatan Prisma, komponen, dan pemisahan Server/Client Component.
Struktur Folder yang Direkomendasikan
nama-project/
├── app/ # Routing & halaman (App Router)
│ ├── (auth)/ # Route group — tidak muncul di URL
│ │ ├── login/
│ │ │ └── page.tsx
│ │ └── register/
│ │ └── page.tsx
│ ├── (dashboard)/
│ │ ├── users/
│ │ │ ├── page.tsx # /users
│ │ │ ├── loading.tsx
│ │ │ └── error.tsx
│ │ └── roles/
│ │ └── page.tsx # /roles
│ ├── api/ # API Routes (kalau perlu endpoint REST)
│ │ └── users/
│ │ └── route.ts
│ ├── generated/ # Hasil generate Prisma Client
│ │ └── prisma/
│ ├── layout.tsx # Root layout
│ ├── globals.css
│ └── page.tsx # Homepage (/)
│
├── components/ # Semua komponen React yang reusable
│ ├── ui/ # Komponen kecil generik (Button, Input, Card)
│ │ ├── Button.tsx
│ │ └── Card.tsx
│ └── features/ # Komponen spesifik per fitur
│ ├── users/
│ │ └── UserTable.tsx
│ └── roles/
│ └── RoleTable.tsx
│
├── lib/ # Utilitas, koneksi eksternal
│ ├── prisma.ts # Singleton Prisma Client
│ ├── auth.ts # Helper autentikasi
│ └── utils.ts # Helper umum (format tanggal, dll)
│
├── types/ # TypeScript types/interfaces custom
│ └── index.ts
│
├── hooks/ # Custom React Hooks
│ └── useDebounce.ts
│
├── prisma/
│ ├── schema.prisma
│ └── migrations/
│
├── public/ # Asset statis (gambar, favicon)
│
├── .env
├── next.config.js
├── tsconfig.json
└── package.json
Penjelasan Tiap Bagian
1. app/ — Khusus Routing
Prinsip penting: app/ sebaiknya cuma isi halaman & routing, bukan tempat menumpuk semua logic. Kalau satu page.tsx mulai panjang dan campur banyak hal (fetch data + tabel + form + tombol), pecah komponennya keluar ke components/.
Contoh yang tadinya terlalu panjang:
// app/roles/page.tsx — semua nempel di sini
export default async function RolesPage() {
const roles = await prisma.role.findMany({ include: {...} })
return (
<div>
{/* 50 baris JSX tabel di sini */}
</div>
)
}
Jadi lebih rapi begini:
// app/roles/page.tsx
import { prisma } from '@/lib/prisma'
import RoleTable from '@/components/features/roles/RoleTable'
export default async function RolesPage() {
const roles = await prisma.role.findMany({
include: { rolecat: true, appmenunew: true },
})
return <RoleTable roles={roles} />
}
// components/features/roles/RoleTable.tsx
export default function RoleTable({ roles }) {
return (
<table>
{roles.map((role) => (
<tr key={role.idrole}>{/* ... */}</tr>
))}
</table>
)
}
Page-nya jadi tipis — cuma tanggung jawab ambil data + kirim ke komponen tampilan. Ini bikin kode gampang dibaca dan gampang di-test.
2. Route Groups (nama) — Mengelompokkan Tanpa Mempengaruhi URL
Folder dengan kurung seperti (auth) atau (dashboard) tidak muncul di URL, cuma untuk pengelompokan visual di kode:
app/(dashboard)/users/page.tsx→ tetap jadi/users, bukan/dashboard/users
Berguna kalau ada banyak halaman dan mau dikelompokkan berdasarkan layout atau fitur, tanpa mengubah struktur URL.
3. components/ui/ vs components/features/
ui/→ komponen kecil, generik, dipakai berulang di banyak tempat (Button, Modal, Input)features/→ komponen yang spesifik untuk satu fitur/domain tertentu (UserTable cuma dipakai di halaman user)
4. lib/ — Semua yang Berhubungan dengan Koneksi/Utilitas Eksternal
Prisma client, koneksi API eksternal, helper autentikasi — semua yang "menghubungkan" aplikasi ke dunia luar ditaruh di sini.
5. Client Component Dipisah dari Server Component
components/features/docscat/
├── DocsCatList.tsx ← Server Component (fetch data)
└── Counter.tsx ← Client Component ('use client')
Penamaan File — Konvensi Umum
| Jenis | Konvensi | Contoh |
|---|---|---|
| Komponen React | PascalCase | UserTable.tsx, Counter.tsx |
| Halaman/routing | lowercase (fixed oleh Next.js) | page.tsx, layout.tsx |
| Utilitas/hooks | camelCase | useDebounce.ts, formatDate.ts |
| Folder route | kebab-case | app/user-profile/page.tsx |
Soal src/ — Perlu atau Tidak?
Ini valid, cuma pilihan gaya:
| Tanpa src/ | Dengan src/ |
|---|---|
app/, lib/, components/ langsung di root |
Semua masuk src/app/, src/lib/, dll |
File config (next.config.js, .env) campur sama folder kode |
File config lebih terpisah jelas dari kode aplikasi |
Tidak ada yang "lebih benar" — cuma soal preferensi kebersihan project. Untuk project baru dengan banyak file config custom, src/ sering direkomendasikan biar root folder tidak berantakan.
Prinsip Utama yang Perlu Diingat
- Jangan taruh semua logic di
page.tsx— pecah ke komponen - Pisahkan Server Component dan Client Component secara eksplisit per file
- Group berdasarkan fitur, bukan berdasarkan tipe file semata (kecuali
components/ui) lib/untuk semua koneksi eksternal, biar gampang di-mock kalau nanti butuh testing