Skip to content

Footer Kondisional di Next.js: Client Kecil, Server Tetap Server

Adityo Guni Waluyo

Menyembunyikan footer di halaman chat tanpa mengorbankan rendering server, lewat pola komposisi resmi Next.js App Router.

Ringkasan

Halaman chat /ai butuh tampilan bersih tanpa footer, tapi menyembunyikannya lewat CSS cuma menutupi masalah, dan menurunkan seluruh layout ke client terlalu boros. Solusinya pola komposisi Next.js: komponen client kecil bernama ConditionalFooter memeriksa usePathname lalu return null di rute /ai. Footer tetap Server Component penuh karena diselundupkan sebagai children, bukan dirombak jadi client.

Halaman chat /ai sudah saya rakit jadi kanvas penuh: full-height, tanpa border, menempel rapi ke tepi viewport. Terasa benar sebagai ruang kerja. Lalu saya scroll ke bawah dan footer situs yang panjang menggantung di bawahnya. Janggalnya mirip jas rapi dengan sandal jepit. Fitur ini butuh halaman yang bersih, bukan kolom kredit di ujungnya.

Dugaan awal saya mengarah ke dua jalan pintas. Pertama, sembunyikan footer lewat CSS untuk rute tertentu. Kedua, ubah layout jadi Client Component supaya bebas membaca route di mana saja. Keduanya jalan, dan keduanya harga matinya mahal. CSS hanya menutup mata: footer tetap dikirim ke browser, tetap di HTML, cuma pura-pura tidak ada. Menurunkan seluruh layout ke client justru memboroskan arsitektur: satu kondisi kecil membayar dengan hilangnya rendering server untuk seluruh pohon UI.

Pola yang benar: client kecil, server sebagai children

Solusinya ada di pola komposisi resmi Next.js. Dokumentasi menjelaskan bahwa Server Component bisa dipass sebagai prop ke Client Component, dan pola umumnya memakai children sebagai slot; yang menarik, Server Component itu tetap dirender di server lebih dulu walau posisinya "di dalam" client component [10]. Jadi saya buat komponen kecil bernama ConditionalFooter: client component berbentuk leaf, sekitar 13 baris, tugasnya satu, memutus render kalau rutenya /ai:

'use client';
import { usePathname } from "@/i18n/navigation";

export default function ConditionalFooter({{ children }}: {{ children: React.ReactNode }}) {{
  const pathname = usePathname();
  if (pathname === "/ai" || pathname.startsWith("/ai/")) return null;
  return <>{{children}}</>;
}}

Pasangnya di layout server yang tetap server:

<ConditionalFooter>
  <Footer />
</ConditionalFooter>

Footer tetap Server Component penuh, tetap dirender di server untuk semua halaman lain. Kondisi "sedang di halaman chat" hanya dipikirkan oleh pembungkus kecil itu, lewat usePathname, hook Client Component untuk membaca pathname URL saat ini [8]. Detail implementasinya persis seperti pesan commit saya: ConditionalFooter membungkus server Footer sebagai children dan return null di route /ai, halaman lain tetap menampilkan footer [9].

Kenapa ini masuk akal

Aturan praktisnya sudah tertulis di dokumentasi: tambahkan 'use client' ke komponen interaktif yang spesifik, jangan menandai bagian UI yang besar sebagai client [10]. ConditionalFooter memenuhi aturan itu dari dua arah. Ia client component paling kecil yang mungkin, dan ia membawa server component sebagai anak, bukan menurunkan orang tua ke client.

Ada catatan riset kecil yang menggigit: banyak tutorial memakai URL lama composition-patterns yang sekarang redirect ke halaman server-and-client-components. Pola ini bukan trik eksotis, dia cara resmi yang diajarkan dokumentasi utama, hanya saja alamatnya pindah. Satu jam merapikan UI menghasilkan pelajaran yang bisa dipakai di mana saja: kondisi client boleh tinggal di daun yang kecil, dan server component yang mahal sebaiknya selalu diposisikan sebagai children yang diselundupkan lewat slot, bukan dirombak jadi client demi satu if statement.

Sumber

Artikel terkait