React Forum
Blog & Guide Responses
Feb 07, 2023 · 04:00 AM

MDN URLSearchParams - discussion (2023-02-07)

Started by Rowan Pierce
externalmdnurlsearchparamsroutingquery parsingdefaultsevidencecontracts

URLSearchParams is deceptively simple: it invites you to treat strings as a router. The MDN page is a helpful anchor because it reminds you what the primitive actually does, which makes it easier to design a stable parse/serialize contract instead of ad-hoc string manipulation.

Read the docs

Do you centralize parse/serialize for query params, or allow components to read params directly? Which keys do you consider share-worthy (belong in URL) versus route-doc-only state? How do you prevent default drift (two components disagree on default sort/filter)?

Comments (16)

Back to latest
Marisol Vega
Feb 10, 2023 · 10:10 AM

Central parse/serialize is non-negotiable for us.

If two components parse the same key differently, you get a "sometimes" bug that never dies.

Dmitri Kline
Feb 14, 2023 · 02:14 PM

We treat query parsing as a contract and we log normalization decisions so they're not invisible:

txt
[tips] query parse q="react" sort=null -> sort="recent" reason=missingDefault
[tips] query normalize removed="page" reason=invalidNumber raw="-1"
[tips] history replaceState to=/search?q=react&sort=recent reason=normalize:query

If the URL changes without that log line, it feels haunted.

Keira Santos
Feb 18, 2023 · 06:06 AM

Counterpoint: not everything belongs in the URL, even if it's easy to serialize.

We keep URL keys to things users care about when sharing (category, sort, query). Panel state and drafts stay internal.

Rowan Pierce
Feb 21, 2023 · 04:04 AM

Same. I like the framing: URL is for human-meaningful keys; docs are for machine-meaningful keys.

If a key doesn't improve sharing, it usually shouldn't be in the URL.

Grace McCoy
Mar 01, 2023 · 03:03 AM

Default drift is real. We solved it by deriving a canonical query object and using it everywhere.

If a component needs a default, it asks the canonical parser, it doesn't invent one.

Jasper Nguyen
Mar 14, 2023 · 02:14 PM

Long-form argument: query params become a schema whether you admit it or not.

If you don't name the schema and version it, you'll end up with accidental backwards compatibility issues and break sharing links silently.

Central parse/serialize + normalization logs are a cheap form of governance.

Nina Kapoor
Mar 29, 2023 · 03:03 AM

We also render a data-query-contract summary in debug mode so screenshots are self-contained.

It prints like q=react sort=recent page=1 and settles arguments fast.

Camille Duarte
Apr 18, 2023 · 06:18 PM

Counterpoint: normalization is dangerous if you do it too aggressively (you can erase user intent).

We log what we changed and we only normalize when we're confident the user didn't mean it (invalid numbers, unknown enums).

Owen Price
May 10, 2023 · 10:10 AM

A nice test strategy: assert on the normalized URL (or the query contract summary) rather than component internals.

If the contract says sort=recent, the UI should reflect it.

Benji Rios
Jun 01, 2023 · 06:06 AM

Long-form counterpoint: URL params are an API surface, and people forget that.

Once your links are shared in docs, tickets, and chat, changing param meaning is a breaking change. Treat it like a versioned API.

Lina Ortega
Jun 25, 2023 · 10:22 PM

Docs tie-in: this maps cleanly to the routing docs: URL is a calm surface; state docs are the richer model.

Related: Routing and Navigation and The App Router Mindset.

Theo Bennett
Aug 19, 2023 · 07:19 PM

We also keep a shareUrl derived string as evidence (the canonical URL for the current posture).

It prevents subtle mismatches where the UI is showing one thing and the share link encodes another.

Salma Qureshi
Dec 31, 2023 · 09:09 AM

MDN isn't glamorous, but it's a stable foundation.

Once you accept how URLSearchParams behaves, you stop fighting it and start designing real contracts around it.

Amina Farouk
Jul 21, 2023 · 07:07 AM

We used enums for query keys and values (typed), and it reduced drift bugs.

The parser becomes the only place where strings exist; the rest of the app uses the typed contract.

Evan Brooks
Sep 18, 2023 · 12:12 PM

A small improvement: log query parse failures with the raw value, but don't crash.

If you crash on unknown params, you've made sharing links fragile.

Harper Iqbal
Oct 15, 2023 · 03:15 PM

Long-form: normalization logs are also a governance tool.

When you see frequent normalizations for one key, it usually means the UI is letting invalid values be produced. Fix the UI, not the parser.

Tomas Rivera
Dec 20, 2023 · 06:18 PM

If you want one rule: never let components parse params directly.

Centralize it and make it produce a query contract summary that you can render and log.