URL adalah kontainer status
(alfy.blog)- Struktur URL bekerja melampaui sekadar alamat, sebagai sarana untuk menyimpan dan memulihkan status aplikasi
- Seperti halaman unduhan PrismJS, ditunjukkan contoh di mana satu URL saja dapat mereproduksi sepenuhnya pengaturan tema, bahasa, dan plugin
- Tiap komponen seperti path, query parameter, dan fragment merepresentasikan berbagai status seperti navigasi hierarkis, pemfilteran, dan navigasi klien
- Hal-hal seperti filter pencarian, pagination, mode tampilan, dan rentang tanggal cocok dimasukkan ke URL, sedangkan informasi sensitif atau status UI sementara tidak cocok
- URL yang dirancang dengan baik meningkatkan kemudahan berbagi, prediktabilitas, dan efisiensi caching, serta memperkuat keandalan aplikasi web dan pengalaman pengguna
Potensi URL
- URL bukan sekadar alamat resource, tetapi juga berfungsi sebagai antarmuka pengguna (UI) dan kontainer status
- Secara otomatis mempertahankan status dalam berbagi, bookmark, riwayat browser, deep link, dan sebagainya
- Telah bekerja sebagai mekanisme dasar manajemen status web sejak 1991
- Setiap komponen URL merepresentasikan jenis status yang berbeda
- Path: penjelajahan resource secara hierarkis (
/users/123/posts) - Query: filter, opsi, dan pengaturan (
?theme=dark&lang=en) - Fragment: lokasi di dalam dokumen atau routing SPA (
#features,#/dashboard)
- Path: penjelajahan resource secara hierarkis (
- Fitur Text Fragments memungkinkan tautan langsung ke teks tertentu di dalam halaman
Pola query parameter
- Menggunakan delimiter untuk menaruh beberapa nilai dalam satu key (
?tags=frontend,react,hooks) - Menserialisasi data bertingkat ke JSON atau Base64 (
?config=eyJyaWNrIjoicm9sbCJ9==) - Boolean flag direpresentasikan melalui keberadaan key (
?mobile) - Bracket notation mengekspresikan banyak nilai dalam bentuk
tags[]=frontend&tags[]=react- Diakui otomatis oleh
qsNode atau middleware Express, tetapi belum distandardisasi
- Diakui otomatis oleh
- Intinya adalah menjaga konsistensi
Contoh representasi status melalui URL
- PrismJS: menyimpan seluruh pengaturan tema, bahasa, dan plugin di hash URL
- GitHub: menyorot rentang baris kode tertentu dengan
#L108-L136 - Google Maps: memasukkan koordinat, level zoom, dan tipe peta ke dalam URL
- Figma: membagikan konteks kerja seperti posisi kanvas, zoom, dan elemen terpilih melalui URL
- Situs e-commerce: memulihkan status pencarian dengan memasukkan filter, pengurutan, dan rentang harga ke URL
Pola rekayasa frontend
- Status yang cocok dimasukkan ke URL
- kata kunci pencarian, filter, halaman dan pengurutan, mode tampilan, rentang tanggal, tab aktif, konfigurasi UI, feature flag
- Status yang tidak cocok untuk URL
- informasi sensitif seperti kata sandi dan token, status UI sementara, input yang belum disimpan, data berukuran besar, status frekuensi tinggi
- Kriteria penilaian: apakah pengguna lain harus melihat status yang sama saat mengklik URL yang sama
Implementasi JavaScript
- API
URLSearchParamsmemungkinkan pembacaan dan penulisan query parameter pushStatemenambahkan entri riwayat baru,replaceStatememperbarui entri saat ini- Event
popstatememulihkan UI saat pengguna menekan tombol kembali di browser
Implementasi React
- Hook
useSearchParamsdari React Router memungkinkan pengelolaan status URL secara ringkas- Saat membaca atau memperbarui parameter, URL dan UI otomatis tersinkronisasi
Praktik terbaik manajemen status URL
- Jangan masukkan nilai default ke URL (cukup pertahankan
?theme=dark, nilai default ditangani dalam kode) - Cegah pembaruan URL berlebihan saat mengetik dengan debouncing (
lodash.debounce) - pushState vs replaceState
pushState: untuk status yang bisa ditelusuri kembali seperti perubahan filter atau perpindahan halamanreplaceState: untuk perubahan halus seperti input pencarian
Melihat URL sebagai kontrak
- URL yang dirancang dengan baik berperan sebagai kontrak eksplisit antara aplikasi dan pengguna
- Menjelaskan batas antara status publik/pribadi, klien/server, dan status berbagi/sesi
- URL yang mudah dibaca menjelaskan maksud dan bisa dipahami manusia maupun mesin
- Bentuk seperti
example.com/products/laptop?color=silver&sort=pricelebih unggul dalam menyampaikan makna
- Bentuk seperti
- Peningkatan efisiensi caching
- URL yang sama dianggap sebagai resource yang sama sehingga tingkat cache hit meningkat
- Variasi cache dapat dikendalikan dengan query parameter
- Manajemen versi dan eksperimen
- API version dan pengujian A/B dapat dibedakan dengan
?v=2,?beta=true,?experiment=new-ui
- API version dan pengujian A/B dapat dibedakan dengan
Antipola yang harus dihindari
- Di SPA hanya mempertahankan status di memori, sehingga status hilang saat halaman dimuat ulang
- Memasukkan informasi sensitif ke URL (
?password=secret123) - Nama parameter yang tidak jelas (
?foo=true&bar=2alih-alih?mobile=true&page=2) - Mengenkode JSON kompleks ke Base64, sehingga menghasilkan URL yang terlalu panjang
- Melewati batas panjang URL (ada batasan dari browser, server, dan CDN)
- Melumpuhkan tombol kembali (terjadi jika
replaceStatedisalahgunakan)
Kesimpulan
- URL yang baik bukan hanya menunjuk konten, tetapi juga mengekspresikan dialog antara pengguna dan aplikasi
- URL adalah sarana manajemen status tertua dan paling elegan untuk memuat niat, konteks, dan kemampuan berbagi
- Meski ada alat manajemen status kompleks seperti Redux, MobX, Zustand, dan Recoil,
tidak melupakan fitur dasar bernama URL adalah kekuatan sejati web - Aplikasi yang kehilangan status saat dimuat ulang sedang mengabaikan sifat hakiki web
2 komentar
Komentar Hacker News
Saat code review, saya berusaha menyimpan sebanyak mungkin state di URL
Dari sudut pandang pengguna, sangat menjengkelkan jika setelah refresh mereka berpindah ke posisi yang benar-benar berbeda, atau URL yang dibagikan justru menampilkan layar yang tidak relevan
Pendekatan ini memang memperlambat kecepatan pengembangan, tetapi membuat kesadaran UX di dalam tim meningkat dan memperjelas seberapa banyak state yang dimuat dalam view
Ada kekhawatiran bahwa URL menjadi semacam API publik sehingga menimbulkan batasan, tetapi menurut saya kebanyakan URL hanya dipakai dalam jangka pendek sehingga bukan masalah besar
Jika perlu, ini bisa diatasi dengan kode untuk memigrasikan URL lama ke URL baru saat dimuat
Saya rasa memakai query parameter lebih baik daripada path
Dari sudut pandang pengguna, kata “back” terhubung dengan tombol browser sehingga membingungkan
State yang di-reset oleh refresh masih lebih tidak menyebalkan. Ada anggapan bahwa “refresh = mulai lagi dari awal”
Kalau semuanya ditangani dengan JS, fitur-fitur dasar seperti ini jadi rusak secara halus
Tetapi sampai sekarang, meskipun sudah bekerja dengan lebih dari 30 desainer UX, saya belum pernah menerima panduan soal URL
Terutama di mobile, sulit mengembalikan halaman ke state awal sehingga refresh menjadi solusi tercepat
Dalam infinite scroll atau UI filter yang kompleks, semakin banyak state di URL maka reset juga makin merepotkan
Jika UX sudah membuat frustrasi, lalu pengguna masih harus membereskan URL juga, itu jadi stres ganda bagi mereka
Saya merasa bahkan orang dengan literasi digital tinggi pun pemahamannya tentang URL dan DNS masih rendah
Mereka seharusnya bisa mengurangi risiko phishing, memahami arti parameter URL (
?t=_,utm_), dan menghapus informasi pribadi sebelum membagikanMereka juga perlu tahu bahwa ikon gembok HTTPS tidak berarti ‘tepercaya’
Jika URL dipakai sebagai state container, struktur internal akan terekspos dan perlu versioning
Masalah juga bisa muncul pada kompatibilitas antar-browser atau alur autentikasi
Meski begitu, saya tetap berusaha mengekspos sebanyak mungkin state ke URL, seperti argumen command line
Namun ini adalah trade-off yang disengaja, bukan karena ketidaktahuan atau kurang pengalaman
Meski library lama, saya tetap merekomendasikan Rison karena masih berguna
JSON bisa disimpan rapi di URL, dan juga dipakai di Kibana milik Elastic
Contoh: http://example.com/service?query=q:'*',start:10,count:10
Saat sistem berkembang, struktur state juga berubah, jadi menaruh state di URL akan membatasi evolusi
Karena pada dasarnya URL adalah string permanen
Sebagai gantinya, saya rasa lebih tepat melihat URL sebagai semacam protokol, lalu state di-encode dan di-decode di atasnya
Untuk halaman yang sederhana, seluruh state juga bisa dimasukkan ke URL
Tetapi untuk hal seperti feed, ini bergantung pada ekspektasi pengguna, misalnya “apakah refresh harus mengembalikan ke state terbaru?”
Batas panjang URL berbeda-beda tergantung pengaturan browser, server, CDN, dan mesin pencari, tetapi umumnya di bawah 2000 karakter
Saya jadi bertanya-tanya berapa banyak state yang bisa dimasukkan dalam batas itu, atau apakah perlu pendekatan lain
- . _ ~), jadi kepadatan informasinya cukup tinggidraw.io bisa menyimpan seluruh state di URL untuk dibagikan
Data diagram di-encode dalam Base64 sehingga satu tautan bisa memulihkan semuanya secara penuh
Namun saya tidak yakin apakah ini benar-benar sesuai dengan definisi ‘state container’
Saya memakai hash routing (#/dashboard) di app self-hosted
Karena tidak perlu URL rewrite di sisi server (.htaccess dan semacamnya), ini setidaknya bisa mengurangi batasan lingkungan deployment, meski tidak sempurna
Microsoft Teams versi terbaru menangani semua layar dengan satu URL sehingga tidak bisa dibookmark
Sangat tidak nyaman karena kita tidak bisa langsung membuka tim atau channel tertentu
HATEOAS kurang mendapat perhatian karena namanya tidak bagus, padahal pada akhirnya itu adalah konsep dasar web
Tetapi dalam lingkungan di mana server dan client sama-sama kita kendalikan, ini hanya menambah kompleksitas
Terutama jika client tetap harus mengetahui struktur endpoint, hasilnya URL hanya dibuat buram
Saya sering memanfaatkan fitur tab tidur, tetapi webapp yang mengunci URL dan bergerak sebagai satu kesatuan akan kehilangan informasi saat masuk ke mode tidur.
Namun, halaman-halaman web seperti itu juga sama-sama berat, jadi rasanya tidak mungkin juga untuk tidak memakai mode tidur.