---
name: typescript-react-nextjs
description: Gunakan skill ini untuk semua pekerjaan yang menyentuh React, Next.js (App Router), atau TypeScript — membuat komponen, routing, data fetching/caching, server actions, state management, forms, performance, atau konfigurasi tsconfig/build. Trigger juga saat membahas migrasi Pages Router ke App Router atau upgrade versi Next.js/React.
---

# ⚡ *React*, *Next.js* & *TypeScript*

## 📅 Versi Acuan Utama (Juli 2026)

1.  **Next.js:** `16.2.10` *Stable* (*App Router default*)
2.  **React:** `19.2.7` *Stable*
3.  **Node.js Runtime:** `22.0+` *Minimum* (`24 LTS` Direkomendasikan)

> [!IMPORTANT]
> *Next.js* sering merilis tambalan keamanan (*security patches*) untuk *Server Components* dan *Proxy*. Selalu periksa dan gunakan versi stabil terbaru sebelum melakukan instalasi. Jalankan perintah `npm show next version` untuk mendapatkan rilis stabil terkini.

---

## 🚀 Perubahan Besar *Next.js 16* (Wajib Diikuti)

1.  **Turbopack Bundler:** Menjadi bundler bawaan (*default*) untuk perintah `next dev` dan `next build`. Seluruh konfigurasi kustom *Webpack* lama harus ditinjau ulang sebelum migrasi dilakukan.
2.  **Proxy System (`proxy.ts`):** Berkas `middleware.ts` kini diubah namanya menjadi `proxy.ts` yang difokuskan sebagai batas jaringan (*network boundary*). Berkas ini wajib mengekspor fungsi `proxy` (atau *export default*).
3.  **Async Request APIs:** Pemanggilan fungsi `cookies()`, `headers()`, `params`, dan `searchParams` bersifat asinkron (wajib menyertakan perintah `await`).
4.  **Opt-In Cache (`"use cache"`):** Secara default, semua kode dinamis akan dieksekusi saat waktu permintaan (*request time*). Mekanisme penyimpanan cache (*caching*) kini bersifat pilihan eksplisit (*opt-in*) dengan menuliskan direktif `"use cache"` di atas modul atau fungsi.
5.  **ESLint/Biome Native:** Perintah bawaan `next lint` telah usang (*deprecated*). Jalankan linter *Biome* atau *ESLint* secara langsung pada root repository.

---

## 📁 Struktur Folder Proyek yang Direkomendasikan

```
src/
├── app/
│   ├── (marketing)/           # Route groups (tidak memengaruhi path URL)
│   ├── (dashboard)/
│   │   ├── layout.tsx
│   │   └── settings/page.tsx
│   ├── api/                   # Route handler khusus webhook/caller eksternal
│   ├── proxy.ts               # Network boundary (pengganti middleware.ts)
│   └── layout.tsx
├── components/
│   ├── ui/                    # Komponen primitif/reusable (Button, Input, dsb)
│   └── features/              # Komponen spesifik untuk fitur tertentu
├── lib/                       # Instansiasi client library (Prisma, Auth, dsb)
├── hooks/                     # Custom react hooks
├── types/                     # TypeScript types/interfaces global
└── actions/                   # Server Actions dikelompokkan per domain/modul
```

---

## 💡 Pola Implementasi Terbaik

### 1. *Server Components* vs *Client Components*
Secara default, buat semua komponen sebagai *Server Components*. Tambahkan direktif `"use client"` hanya di ujung hierarki pohon komponen (*leaf components*) yang benar-benar membutuhkan *browser API*, kait status (*hooks state*), atau pemantau aktivitas (*event listeners*).

### 2. *Server Actions* & *Zod Validation*
Lakukan validasi data dari form secara ketat menggunakan pustaka *Zod* di dalam *Server Actions* sebelum melakukan operasi penyimpanan data ke basis data. Jangan pernah mempercayai data mentah dari objek `FormData`.

```ts
"use server";
import { z } from "zod";

const UserSchema = z.object({
  email: z.string().email("Format email tidak valid"),
  name: z.string().min(1, "Nama tidak boleh kosong"),
});

export async function createUser(formData: FormData) {
  const parsed = UserSchema.safeParse(Object.fromEntries(formData));
  if (!parsed.success) {
    return { error: parsed.error.flatten() };
  }
  // Lakukan query database dengan parsed.data
}
```

### 3. Pemrosesan & Penyimpanan Data (*Data Fetching & Caching*)
1. Gunakan fungsi bawaan `fetch()` dengan direktif cache yang eksplisit atau jalankan kueri asinkron langsung di dalam *Server Component*.
2. Manfaatkan pustaka *TanStack Query* untuk data yang membutuhkan interaktivitas dinamis pada sisi klien (seperti pencarian *live*, penarikan data berkala atau *polling*, serta gulir tanpa batas atau *infinite scroll*).
3. Gunakan *Zustand* untuk manajemen status klien global (*global client state*) yang kompleks. Hindari penggunaan *Redux* kecuali untuk memelihara proyek lama (*legacy project*).

---

## 🛡️ Aturan Strict *TypeScript* (Non-Negotiable)

> [!WARNING]
> Penggunaan tipe data `any` sangat dilarang keras. Selalu definisikan tipe data yang spesifik atau gunakan tipe data `unknown` diikuti dengan penyempitan tipe (*type narrowing*).

Konfigurasi minimal berkas `tsconfig.json` yang wajib diaktifkan:

```json
{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "moduleResolution": "bundler",
    "target": "ES2022",
    "skipLibCheck": true,
    "verbatimModuleSyntax": true
  }
}
```

*   **Named Exports:** Gunakan ekspor bernama (*named exports*) secara bawaan (misalnya: `export const MyComponent = ...`) untuk mempermudah proses penataan ulang kode (*refactoring*) dan pelacakan oleh perkakas kerja (*tooling*). Gunakan *default export* hanya jika diwajibkan oleh konvensi struktur berkas *framework* (seperti pada file `page.tsx` atau `layout.tsx`).

---

## ❌ Hal yang Harus Dihindari dalam Pengembangan Frontend

*   **Create React App (CRA):** Menggunakan *CRA* yang telah usang. Gunakan *Vite* untuk aplikasi halaman tunggal (*single page application* / SPA) murni, atau *Next.js* untuk aplikasi *fullstack* berbasis SSR.
*   **Class Components:** Menulis komponen berbasis kelas baru. Gunakan komponen fungsi (*function components*) yang dikombinasikan dengan *React Hooks*.
*   **useEffect Data Fetching:** Melakukan penarikan data menggunakan *hook* `useEffect` pada sisi klien untuk data yang seharusnya bisa ditarik langsung di tingkat *Server Component*.
*   **Duplicate Server State:** Menyimpan salinan data basis data ke dalam pengelola status klien (seperti *Zustand*), yang mengakibatkan inkonsistensi data dengan sumber kebenaran utama (*source of truth*).
*   **Direct Google Fonts CDN:** Menggunakan tautan *Google Fonts* secara langsung melalui tag HTML `<link>`. Gunakan modul resmi `next/font` untuk mengunduh dan menyajikan berkas font secara lokal saat waktu kompilasi (*build time*).
