URL-PATTERN WEB-API JAVASCRIPT FRONTEND ROUTING WEB-DEVELOPMENT BROWSER URL-MANAGEMENT SPA DEVELOPER-EXPERIENCE WEB-STANDARDS MODERN-JAVASCRIPT

Menguasai URLPattern API: Membangun Routing dan Logika URL yang Cerdas di Browser

⏱️ 6 menit baca
👨‍💻

Menguasai URLPattern API: Membangun Routing dan Logika URL yang Cerdas di Browser

Sebagai developer web, kita sering berurusan dengan URL. Mulai dari membuat sistem routing di Single Page Application (SPA), mengekstrak parameter dari URL, hingga memastikan URL yang masuk ke backend memiliki format yang benar. Secara tradisional, pekerjaan ini sering melibatkan penggunaan Regular Expressions (regex) yang kompleks dan terkadang sulit dibaca atau di-maintain.

Tapi bagaimana jika ada cara yang lebih mudah, lebih deklaratif, dan bahkan merupakan standar web native untuk menangani semua itu?

Inilah saatnya Anda mengenal URLPattern API. 💡

1. Pendahuluan: Ucapkan Selamat Tinggal pada Regex URL yang Rumit!

Bayangkan Anda memiliki aplikasi web dengan berbagai rute dinamis, seperti /users/:id, /products/:category/:productId, atau bahkan URL dengan query string seperti /search?q=keyword&page=1. Bagaimana Anda biasanya menanganinya? Mungkin dengan String.prototype.match() atau RegExp.prototype.exec() yang hasilnya perlu Anda parse lagi secara manual.

// Contoh lama dengan regex
const path = "/users/123/profile";
const userPathRegex = /^\/users\/(\d+)\/profile$/;
const match = path.match(userPathRegex);

if (match) {
  const userId = match[1];
  console.log("User ID:", userId); // Output: User ID: 123
} else {
  console.log("Path tidak cocok.");
}

Pendekatan ini bekerja, tetapi memiliki beberapa kelemahan:

URLPattern API hadir untuk menyederhanakan proses ini. Ia menyediakan cara deklaratif dan terstruktur untuk mendefinisikan pola URL, mencocokkan URL yang ada, dan mengekstrak informasi darinya, jauh lebih mudah dibaca dan dikelola daripada regex murni. Ini adalah standar web native, artinya Anda tidak perlu library pihak ketiga untuk menggunakannya di browser yang mendukung.

Mari kita selami lebih dalam!

2. Memahami Dasar URLPattern

Membuat URLPattern sangat mirip dengan membuat URL atau URLSearchParams. Anda cukup membuat instance baru dari URLPattern dengan pola URL yang Anda inginkan.

Pola ini bisa mencakup berbagai komponen URL: protocol, hostname, port, pathname, search, dan hash.

// Buat pola untuk URL
const userProfilePattern = new URLPattern({
  pathname: "/users/:id/profile",
});

// Atau pola yang lebih lengkap
const fullProductPattern = new URLPattern({
  protocol: "https",
  hostname: "{subdomain}.example.com",
  pathname: "/products/:category/:productId",
  search: "?sort=:sortBy",
  hash: "#section-:sectionId",
});

📌 Sintaks Pola:

Metode Penting: test() dan exec()

URLPattern memiliki dua metode utama untuk bekerja dengan URL:

3. Ekstraksi Parameter Dinamis dengan Mudah

Salah satu kekuatan terbesar URLPattern adalah kemampuannya mengekstrak parameter dinamis dari URL secara otomatis. Parameter ini akan tersedia dalam objek groups di dalam properti komponen (pathname, search, hash, dll.) dari URLPatternResult.

const productDetailPattern = new URLPattern({
  pathname: "/products/:category/:productId",
  search: "?promo=:promoCode&ref=:referrerId?", // `?` setelah :referrerId berarti opsional
});

const url1 = "https://shop.example.com/products/electronics/laptop-x1?promo=BIGSALE&ref=partnerA";
const url2 = "https://shop.example.com/products/books/novel-fantasi?promo=FREESHIP";
const url3 = "https://shop.example.com/products/clothing/tshirt"; // Tidak cocok dengan search

const result1 = productDetailPattern.exec(url1);
const result2 = productDetailPattern.exec(url2);
const result3 = productDetailPattern.exec(url3);

if (result1) {
  console.log("URL 1:");
  console.log("  Kategori:", result1.pathname.groups.category); // electronics
  console.log("  Product ID:", result1.pathname.groups.productId); // laptop-x1
  console.log("  Promo Code:", result1.search.groups.promoCode); // BIGSALE
  console.log("  Referrer ID:", result1.search.groups.referrerId); // partnerA
}

if (result2) {
  console.log("\nURL 2:");
  console.log("  Kategori:", result2.pathname.groups.category); // books
  console.log("  Product ID:", result2.pathname.groups.productId); // novel-fantasi
  console.log("  Promo Code:", result2.search.groups.promoCode); // FREESHIP
  console.log("  Referrer ID:", result2.search.groups.referrerId); // undefined (karena opsional)
}

if (!result3) {
  console.log("\nURL 3 tidak cocok karena search parameter tidak ada atau tidak sesuai.");
}

Seperti yang Anda lihat, parameter seperti :category, :productId, :promoCode, dan :referrerId langsung diekstrak ke dalam objek groups yang mudah diakses. Ini jauh lebih bersih daripada memanipulasi array hasil regex.

4. Studi Kasus 1: Routing Frontend yang Lebih Bersih

Salah satu aplikasi paling jelas dari URLPattern adalah untuk routing di aplikasi frontend Anda. Daripada menulis logika regex yang rumit untuk setiap rute, Anda bisa mendefinisikannya secara deklaratif.

// router.js
const routes = [
  {
    pattern: new URLPattern({ pathname: "/" }),
    handler: () => renderHomePage(),
  },
  {
    pattern: new URLPattern({ pathname: "/products/:category/:id" }),
    handler: (params) => renderProductPage(params.category, params.id),
  },
  {
    pattern: new URLPattern({ pathname: "/users/:userId/profile" }),
    handler: (params) => renderUserProfilePage(params.userId),
  },
  {
    pattern: new URLPattern({ pathname: "/search" }),
    handler: (params) => renderSearchPage(params.q), // params.q dari search string
  },
];

function handleRouting() {
  const currentUrl = window.location.href;

  for (const route of routes) {
    const match = route.pattern.exec(currentUrl);
    if (match) {
      // Menggabungkan semua grup dari pathname, search, hash, dll.
      const allParams = {
        ...match.pathname.groups,
        ...match.search.groups,
        ...match.hash.groups,
      };
      route.handler(allParams);
      return;
    }
  }
  renderNotFoundPage();
}

// Contoh fungsi render (placeholder)
function renderHomePage() { console.log("Menampilkan halaman beranda."); }
function renderProductPage(category, id) { console.log(`Menampilkan produk ${id} dari kategori ${category}.`); }
function renderUserProfilePage(userId) { console.log(`Menampilkan profil pengguna ${userId}.`); }
function renderSearchPage(query) { console.log(`Menampilkan hasil pencarian untuk: ${query || 'kosong'}.`); }
function renderNotFoundPage() { console.log("Halaman tidak ditemukan."); }

// Event listener untuk perubahan URL (misalnya dari link atau history.pushState)
window.addEventListener("popstate", handleRouting);
document.addEventListener("DOMContentLoaded", handleRouting); // Initial load

// Contoh navigasi programatik
function navigateTo(path) {
  window.history.pushState({}, "", path);
  handleRouting();
}

// Coba navigasi
// navigateTo("/");
// navigateTo("/products/books/123");
// navigateTo("/users/john.doe/profile");
// navigateTo("/search?q=javascript+tutorials");
// navigateTo("/non-existent-page");

✅ Dengan URLPattern, logika routing Anda menjadi lebih deklaratif, mudah dibaca, dan jauh lebih rapi. Anda bisa dengan cepat melihat pola URL dan parameter apa yang akan diekstrak.

5. Studi Kasus 2: Validasi dan Normalisasi URL

Selain routing, URLPattern juga sangat berguna untuk validasi URL. Anda bisa menggunakannya untuk memastikan URL yang dikirimkan pengguna atau diterima dari sumber eksternal sesuai dengan format yang diharapkan.

const allowedImagePattern = new URLPattern({
  protocol: "https",
  hostname: "{domain}.cdn.example.com",
  pathname: "/images/**.{png|jpg|jpeg|gif}", // Menggunakan regex di dalam kurung kurawal untuk ekstensi
});