Girish Lade.
Developer ToolsPublished 2026-11-015 min read

Deterministic URL Normalization and Local Visual Bookmarking at Scale

How Visual Bookmark Manager strips tracking parameters, handles canonical duplicates, and manages thousands of visual resources locally in IndexedDB.

Over a career in software development, you collect thousands of URLs: documentation articles, GitHub repositories, RFC proposals, and design systems. Browser bookmark managers quickly devolve into messy, disorganized graveyards filled with broken duplicates and bloated tracking strings.

The same article saved from Twitter, Reddit, and LinkedIn often contains distinct query parameters (?utm_source=twitter, ?ref=hn, #heading-3). To a standard bookmark tool, these represent three distinct records.

I built the Visual Bookmark Manager (bookmark.ladestack.in) to deliver an intelligent, visually indexed repository with deterministic URL canonicalization.

The URL Canonicalization Engine

Before saving any bookmark, the URL is processed through a strict normalization algorithm:

const TRACKING_PARAMS = new Set([
  'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',
  'fbclid', 'gclid', 'msclkid', 'mc_eid', '_hsenc', 'ref', 'source'
]);

export function canonicalizeUrl(rawUrl: string): string {
  try {
    const url = new URL(rawUrl.trim());

    // Normalize protocol and lowercase hostname
    url.protocol = url.protocol.toLowerCase();
    url.hostname = url.hostname.toLowerCase();

    // Strip trailing slashes for path consistency
    if (url.pathname.length > 1 && url.pathname.endsWith('/')) {
      url.pathname = url.pathname.slice(0, -1);
    }

    // Strip marketing trackers while preserving functional parameters
    const searchParams = new URLSearchParams(url.search);
    for (const key of Array.from(searchParams.keys())) {
      if (TRACKING_PARAMS.has(key.toLowerCase()) || key.startsWith('utm_')) {
        searchParams.delete(key);
      }
    }

    // Sort query parameters to avoid order variations
    searchParams.sort();
    url.search = searchParams.toString() ? `?${searchParams.toString()}` : '';

    // Strip non-semantic fragments
    url.hash = '';

    return url.toString();
  } catch {
    return rawUrl.trim();
  }
}

High-Performance Storage with IndexedDB

Storing rich metadata (titles, previews, user tags, and favicon data) for 5,000+ bookmarks exceeds the 5MB quota of standard localStorage. Visual Bookmark Manager utilizes an asynchronous IndexedDB schema with compound indices over tags, creation timestamps, and domain names.

Search queries execute in sub-millisecond timeframes using in-memory inverted indices, providing a lightning-fast experience without needing a cloud database.