I’m building a help desk application and need to create a URL routing system that works like Gmail. My page has two main areas:
Area 1: Filter controls (new tickets, resolved tickets, assigned to me, priority tickets, etc). Users can pick multiple filters at once.
Area 2: Ticket list that updates based on the selected filters.
Here’s what I want to achieve:
When users change filters, the URL should update automatically so they can bookmark specific views
The ticket list should refresh via AJAX without reloading the entire page
The same code should handle both scenarios: when someone clicks filters AND when they visit a bookmarked URL
My current approach is to use URL fragments (the part after #) to store filter states. When filters change, I update the hash and trigger a function called loadTickets() that reads the URL, extracts the filters, and makes an AJAX call. I also call this same function on page load.
Is this the right approach? What would be the most effective way to build this kind of URL routing system?
Your fragment approach is solid - I used something similar for a project management dashboard last year and it worked great. The big win is avoiding full page reloads, so your AJAX updates stay smooth. One gotcha I ran into: debounce your URL updates when users hit multiple filters quickly. Without it, you’ll get performance issues and a messy browser history. I went with 300ms before updating the hash and firing the AJAX call. Also build a fallback for invalid filter combos in the hash. Users love manually editing URLs or sharing broken links. I just fall back to defaults and show a quick ‘invalid parameters’ message. Keeps everything from completely breaking.
I disagree with ditching hash routing entirely. Yeah, the History API gives cleaner URLs, but hash-based routing has real advantages here. Hash changes don’t hit the server, so your backend doesn’t need to handle all those filter combinations. I built a similar ticketing system two years ago and started with pushState but hit problems when users shared URLs - the server had to render every possible filter state. With hash routing, your server just serves the base page and JS handles the rest. Way simpler to deploy. Just implement a solid state parser that handles malformed hashes gracefully. I’d stick with your current approach but add proper error handling and maybe compress complex filter states into shorter hash strings for sharing.
Hash routing’s outdated - just use the History API instead. pushState/popState gives you clean URLs without that ugly # symbol. Better for SEO and users too. Listen for popstate events when they hit back/forward, then update your filters. I’ve been using this for years and it’s way cleaner than fragment routing.