Introduction
Price range filters like "under ¥25,000" or "¥25,001–¥50,000" are a staple of every EC site. Precisely because they look simple, the problems tend to surface only after launch: a range is selectable on screen but errors out when applied, or you want to adjust the ranges but so many places need editing that nobody wants to touch them.
This article explains how we built a price range filter that stays maintainable and hard to break, by consolidating the range definitions in one place — an approach called SSOT (Single Source of Truth: keeping exactly one authoritative copy of a piece of information).
Three Problems Price Range Filters Tend to Have
Definitions Scatter Across the Codebase
A price range filter needs at least two places to know which ranges exist: the part that displays the options on screen, and the part that filters products by the selected condition. Define the ranges separately in each place, and sooner or later someone updates one and forgets the other. When a range is selectable in the UI but errors out on search, a mismatch like this is almost always the cause.
Every Change Means Editing Multiple Places
Suppose you want to switch from ¥25,000 increments to ¥30,000 increments. With scattered definitions, you have to hunt down and edit every related spot — the display, the filtering logic, the URL parsing. Beyond the sheer effort, the risk of missing one spot accompanies every single change. Honestly, the ranges become something you avoid changing at all.
Saved URLs Stop Working
Filter conditions are carried in the URL, which means users bookmark filtered views. If a redesign drops support for the old URL format, those bookmarks open to a page where the filter no longer applies. A change meant as an improvement reads as "the site broke" to the users affected.
The Solution — One File Holds Every Price Range Definition
Everything References the Same Definition
Our approach: put the price range definitions (the boundaries of each range and the label it displays under) into a single file, and have the screen display, the filtering logic, and the URL parsing all reference that one place. With exactly one definition, the referencing parts cannot disagree with each other. It's the SSOT idea applied to a filter.
Ranges Are Chosen to Match Buying Behavior
The definition file holds these five ranges.
As the table shows, each range gets an ID like range_1, paired with its boundaries and display label. The boundaries themselves were chosen from the catalog's price distribution and typical user budgets.
How a Filter Request Flows
From the moment a user picks a range to the moment products appear:
In one sentence: the URL only carries a range ID, and everything asks the definition file what that ID actually means.
What Centralization Made Easier
Changes Are a One-File Edit
To adjust the ranges, edit the definition file — that's it. The on-screen options, the filtering logic, and the URL parsing all read the same definition, so they pick up the new ranges automatically. With no risk of a missed spot, even experimental tweaks like "let's try different boundaries" become low-stakes.
"Selectable but Broken" Can't Happen
Because the definition exists in exactly one place, the screen and the server can never disagree about which ranges exist. The point isn't that we fixed a bug — it's that the structure makes that class of bug impossible. That's how SSOT pays off.
Old URLs Keep Working
URLs saved in the previous format (for example 0-25000) are automatically converted to the new ID format (range_1) when opened. The conversion itself also references the definition file, so future range changes won't leave the conversion rules behind. We modernized the internals without breaking a single user's bookmark.
In one sentence: when a URL arrives in the old style, it's translated to the current style at the door before entering normal processing.
Summary
The reliability of a price range filter depends less on where you draw the price boundaries than on where you manage their definition. Consolidating everything into one file gave us one-place changes, structurally impossible mismatches, and old URLs that keep working. For staple features like this one, designing for maintainability upfront is what keeps them cheap to live with later.