How Price Range Filters Work

Centralized price range definitions for easy management and user-friendly filters

Price RangeFilterSSOTUXCentralized Management
5 min read

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:

Price Range Filter Processing
User selects a range
Clicks "Under ¥25,000"
Condition appended to URL
?priceRange=range_1
Definition file consulted
range_1 means "¥0–25,000"
Price condition sent to Shopify
Query for products from ¥0 to ¥25,000
Matching products returned
Filtering complete

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.

Handling the Old URL Format
Old URL
?priceRange=0-25000
Conversion
Look up the mapping in the definition file
Processed as the new format
?priceRange=range_1

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.