Bukan Tutorial, Ini Cerita Insafnya Pembenci App Router di Next.js

Bukan Tutorial, Ini Cerita Insafnya Pembenci App Router di Next.js

Zakiego

Zakiego

@zakiego

Sekali lagi, tulisan ini bukanlah tutorial, namun cerita dari insafnya seorang pembenci App Router pada Next.js. Bahasa yang digunakan mungkin mengandung banyak istilah, untuk memudahkan, akan diarahkan ke dokumentasi terkait.

Saat menulis ini, versi Next.js yang digunakan adalah versi 13. Sedangkan saat tulisan ini dipublish, tepat dengan diumumkannya Next.js versi 14.

Pendahuluan

App Router adalah sebuah paradigma baru yang diperkenalkan sejak versi 13. Jika kamu masih menggunakan versi 13 ke bawah, maka sudah bisa dipastikan masing menggunakan Pages Router.

Apa perbedaannya?

Perbedaan paling mencoloknya, jika App Router menggunakan folder /app untuk membuat halaman. Sedangkan Pages Router menggunakan folder /pages.

# Struktur folder Pages Router
├── package.json
├── pages
   ├── _app.js
   ├── index.js
   ├── about.js

# Struktur folder App Router
├── package.json
├── app
   ├── page.js
   ├── layout.js
   ├── about
   ├── page.js

Pembahasan

Keresahan

Saat itu, sepulang dari KKN (--nasib masih mahasiswa 🥲). Setelah selama sebulan menjadi warga desa, dan berjarak sangat lama dengan kodingan.

Di meeting pertama, ditunjukkan oleh mas Fikry dan mas Sonny, sebuah project kantor yang bereksperimen menggunakan App Router.

Dalam hati bergumam, "Berani juga pakai App Router, perasaan di Twitter masih banyak yang nggak sreg sama App Router, entah itu karena bug atau sekadar komplain karena aneh" 😅.

Namun, karena itu sebatas landing page, aman saja untuk bereksperimen. Bukan sebuah sistem kompleks yang melibatkan banyak interaksi.

Kodingannya masih full menggunakan use client. Kegelisahan ini juga tersampaikan ke mas Sonny, "Mas, ini kalau full pakai use client, terus fungsi React Server Component apa ya?". Pertanyaan yang kemudian baru saja akhir-akhir ini saya temukan jawabannya.

Sebagai catatan, di kantor menggunakan Chakra-UI (yes, karena membantu develop UI dengan cepat!) sebagai library component. Sayangnya, Chakra-UI sampai hari ini masih harus menggunakan use client. Tidak seperti Tailwind CSS yang bisa menggunakan full server.

Langkah Pertama

Setelah beberapa waktu, tibalah saatnya. Mendapatkan mandat untuk membuat sebuah user management, dengan menggunakan Next.js App Router.

Membuat project lucu-lucuan dengan App Router saja tidak pernah, ini langsung bikin untuk keperluan serius.

Rasanya? Antara yakin dan tidak dengan diri sendiri, apakah akan berhasil? 🙂

Tidak berhenti sampai situ. Masih ada hal menarik. Jika biasanya menggunakan Prisma sebagai ORM dan NextAuth.js sebagai autentikasi, kali ini menggunakan library yang baru. Bukan baru dipakai, tapi benar-benar baru lahir, alias baru rilis ke pasaran.

Kalau istilah tech twitter, bleeding edge 🤣. Sederhananya, pakai teknologi baru yang belum teruji lama di pasaran oleh developer, sehingga rawan ada banyak bug. Bisa berdarah-darah 🥶.

Library yang dimaksud adalah Drizzle sebagai ORM dan Lucia sebagai autentikasi.

Proses

Seingat saya, sebelum mengerjakan project serius ini, sudah sempat membaca tulisan-tulisan milik mas Nauval, yang pertama mengetuk hati soal App Router.

Hari demi hari berlalu. Membaca dokumentasi App Router menjadi teman setia. Saya jarang bertanya, lebih senang mencari tahu sendiri, kecuali jika memang sudah sangat buntu.

Kemampuan membaca dokumentasi sangat penting, apalagi saat mempelajari teknologi terbaru. Karena biasanya, rilis pertama masih berupa tulisan, sedikit yang membuat video tutorialnya. Dan juga, jika dibandingkan, resource dalam bentuk tulisan selalu lebih banyak, dibandingkan video.

Langkah pertama saya dimulai dengan belajar mengenai form. Banyak waktu dihabiskan hanya untuk mempelajari bagaimana form bekerja dengan server secara langsung? Bagaimana menggunakan formData? Bagaimana membuat actions.ts?

Saat proses ini, tidak banyak progres mengenai UI yang dibuat. Namun setelah mulai mengerti cara mainnya, dan menemukan polanya. Pekerjaan terasa mudah, serius.

Di Penghujung

Sekitar satu bulan kemudian, fitur-fitur utama dari project user management ini selesai. 🥳🎉

Tidak disangka, saya yang awalnya ragu dengan App Router, ternyata berhasil menyelesaikan sebuah sistem dengan paradigma ini.

Bertanya Jawab

Bagaimana perasaannya, apakah akan tetap menggunakan App Router atau kembali ke Pages Router?

Dengan beribu maaf, saya telah luluh dengan App Router. Jika disuruh memilih, saya akan tetap menggunakan di App Router.

Setelah menyelesaikan project di tulisan ini, setiap saya membuat project baru, selalu menggunakan App Router, tidak pernah lagi meng-init project dengan Pages Router.

Apa hal yang awalnya dikira A, ternyata realitnya B, dari App Router?

"use client" 😅

Awalnya mengira, jika sebuah page menggunakan use client, maka semua komponen di dalamnya akan menjadi client juga. Ternyata tidak demikian. Di dalam sebuah page yang menggunakan use client, bisa memiliki component yang merupakan server component. 🤯

Di sinilah seninanya, kita bisa mengurangi beban mentahan yang dikirim ke client. Dengan melakukan sebagian render di server, dan sisanya, baru dibebankan ke client.

Apa fitur yang membuat terpikat dengan App Router?

Sebenarnya ada banyak, salah satunya adalah kemudahan untuk bisa mengakses lewat server, tidak harus getServerSideProps. Simak kode di bawah ini.

// app/dashboard/Header.tsx
// server component ☁️

async function getUser() {
  const data = await fetch("/api/user").then((res) => res.json());
  return data;
}

export function Header() {
  const user = getUser();
  return <p>{user.name}</p>;
}
// app/dashboard/page.tsx
// client component 🗻

'use client' 

function Page() {
  return (
    <Header /> // ini server component 😎
    <Content />
    <Footer />
  );
}

Baca pelan-pelan. Kita bisa meletakkan server component, di dalam client component! Sehingga, kita bisa menghindari props drilling dari getServerSideProps. Cukup letakkan fetch di dekat komponen yang memerlukannya.

Selain itu, karena melakukan fetch di server, kita tidak perlu memikirkan bagaimana saat onLoading jika fetch di client. Dan juga, karena fetch dilakukan di server, kita bisa mengakses .env yang diperlukan, tanpa harus membuat endpoint API khusus.

Apa kabar dengan tRPC?

Jika teman-teman pernah membaca di bio twitter saya (@zakiego), di sana tertulis saya pengguna tRPC.

Namun setelah menggunakan App Router, tidak lagi menggunakannya. Lebih senang menggunakan "use server" kemudian digabungkan dengan Zod untuk melakukan validasi.

Jika ada pertanyaan lain, jangan sungkan untuk mengutarakannya! Agar bisa ditambahkan pada bagian ini.

Buah Tangan

Beginilah struktur file saat menggunakan App Router sekarang.

Penjelasan:

  • action.ts untuk membuat function yang dijalankan di server.
  • page-client.tsx untuk page karena Chakra UI masih full client.
  • page.tsx sebagai tempat utama meletakkan <PageClient />, karena page.tsx inilah yang diakui oleh Next.js sebagai page.
  • schema.ts untuk melatkkan skema dari Zod yang kemudian di-infer dan digunakan di action.ts dan page-client.ts untuk keperluan mengirim dan menerima data.

Penutup

Next.js baru merilis materi pembelajaran baru yang bisa diakses melalui https://nextjs.org/learn. Saya sangat merekomendasikan untuk mempelajari course official ini.

Pada akhirnya, apa pun teknologi yang kita pilih, diskursus ini hanya terbatas pada kalangan sesama developer. Sedangkan user tidak mau tau, yang mereka mau adalah aplikasi yang bisa diakses tanpa lemot. 😅


Mulai ditulis pada 7 Oktober 2023 di Banjarmasin.

Diselesaikan pada siang hari Jum'at, 27 Oktober 2023 di Kantor Desa Bambangin.