Next.jsReactTailwind CSSUI/UX

Membangun Portofolio Interaktif dengan Next.js App Router & Full-Page Snap

Mohammad Luqi

Mohammad Luqi

Software Engineer & Fullstack Developer

15 Maret 2026•6 menit•342 baca
Membangun Portofolio Interaktif dengan Next.js App Router & Full-Page Snap

#Pendahuluan

Membuat website portofolio developer sering kali terjebak dalam dua kutub: terlalu sederhana seperti dokumen CV statis, atau terlalu berat dengan animasi 3D yang membuat kipas laptop berputar kencang dan lambat diakses di smartphone.

Dalam proyek portofolio ini, tujuannya jelas: **menciptakan pengalaman eksplorasi yang imersif (One-Page Full Scroll) dengan performa kilat, animasi hemat daya (GPU-accelerated), dan pengalaman navigasi yang intuitif di perangkat desktop maupun mobile.**


#1. Fondasi CSS Scroll Snap Murni

Alih-alih mengandalkan library JavaScript pihak ketiga yang membajak scroll bawaan browser (*scroll jacking*), kami memanfaatkan fitur bawaan browser modern: **CSS Scroll Snap**.

Keuntungan utama: - **Nol JavaScript overhead** untuk kalkulasi momentum scroll. - Berjalan pada *compositor thread* browser sehingga 60-120 FPS mulus di layar ProMotion / High Refresh Rate. - Tetap ramah aksesibilitas keyboard (panah atas, bawah, Page Up, Page Down).

```css /* Wrapper Utama */ #scroll-container { height: 100vh; width: 100%; overflow-y: scroll; scroll-snap-type: y mandatory; scroll-behavior: smooth; scrollbar-width: none; /* Firefox */ -ms-overflow-style: none; /* IE / Edge */ }

#scroll-container::-webkit-scrollbar { display: none; /* Safari & Chrome */ }

/* Setiap Section Anak */ section { width: 100%; height: 100vh; scroll-snap-align: start; scroll-snap-stop: always; } ```


#2. Sinkronisasi State Aktif dengan Custom Event

Tantangan arsitektur saat membungkus section dalam container ber-scrollsnap terisolasi adalah: `window.scrollY` bernilai 0 karena yang bergulir adalah elemen container internal (`#scroll-container`).

Solusinya adalah membuat **FullPageScrollWrapper** yang memantau `scrollTop` container menggunakan `requestAnimationFrame`, lalu menyiarkan Custom Event ke seluruh aplikasi:

|typescript
// FullPageScrollWrapper.tsx
window.dispatchEvent(
  new CustomEvent("fullpage-section-sync", {
    detail: {
      activeId: sec.id,
      progress: Math.min(Math.round(scrollPercent), 100),
    },
  })
);

Dengan pendekatan *event-driven* ini: 1. **Side Dot Navigation** di sisi samping langsung mengetahui titik mana yang sedang aktif tanpa re-render berlebihan. 2. **Ambient Backdrop** mengubah temperatur gradasi warna atmosferik di latar belakang secara halus sesuai tema section.


#3. Strategi Navigasi Hybrid (Desktop vs Mobile)

Pengalaman layar lebar sangat berbeda dengan interaksi sentuh pada gawai: - **Di Desktop:** Kami menyediakan *Side Dot Capsule* di tepi kanan layar dengan label tooltip saat kursor mendekat, serta menu *Command Palette* (`⌘K`) untuk navigasi instan via keyboard. - **Di Mobile:** Area tepi kanan layar dibebaskan dari dot agar ibu jari pengguna dapat menggeser layar (*swipe gesture*) dengan nyaman tanpa salah sentuh. Navigasi lengkap dipindahkan ke dalam *Fullscreen Slide Menu*.


#Kesimpulan

Membangun web modern bukan tentang memasukkan sebanyak mungkin library animasi, melainkan bagaimana memaksimalkan kapabilitas platform web modern (CSS modern, Next.js Server Components, dan arsitektur event yang rapi) untuk melayani pengguna secara elegan dan berkecepatan tinggi.