Skip to content

feat: add required parser option for loaders - #1504

Open
Cauatn wants to merge 4 commits into
47ng:nextfrom
Cauatn:feat/loader-required-option
Open

feat: add required parser option for loaders#1504
Cauatn wants to merge 4 commits into
47ng:nextfrom
Cauatn:feat/loader-required-option

Conversation

@Cauatn

@Cauatn Cauatn commented Jul 24, 2026

Copy link
Copy Markdown

Summary

  • Parsers can opt into withOptions({ required: true }) so createLoader/loadSearchParams throws when a key resolves to null (missing from the URL, or failed to parse) and there is no defaultValue to fall back to. A defaultValue always satisfies the requirement, even when the param itself is absent from the URL.
  • Adds test coverage for the new option, including interaction with strict mode.
  • Documents the new option in the server-side usage docs, gated behind <SinceVersion v="2.10.0"> until released.

Closes #1404

Test plan

  • vitest run --project unit src/loader.test.ts passes (26/26)
  • Typecheck clean on loader.ts

Cauatn and others added 3 commits July 24, 2026 14:45
Parsers can opt into `withOptions({ required: true })` so `createLoader`
throws when a key resolves to `null` (missing from the URL, or failed to
parse) and no `defaultValue` is set to fall back to.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 24, 2026

Copy link
Copy Markdown

@Cauatn is attempting to deploy a commit to the 47ng Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 86f92604-d9d0-439a-9b14-9e546cec8b60

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@franky47

Copy link
Copy Markdown
Member

Hum this feels redundant with strict, what's your actual use-case for this?

@Cauatn

Cauatn commented Aug 1, 2026

Copy link
Copy Markdown
Author

Hum this feels redundant with strict, what's your actual use-case for this?

strict throws when a value is present but invalid (e.g. ?count=banana). It doesn't do anything when the key is missing entirely from the URL, in that case the loader just silently falls back to null (or the default, if one exists).

required targets: "this key must exist in the URL at all, not just be well-formed if it happens to be there."

A concrete case that motivated this: a page like /orders/detail?orderId=4821, where the page has no meaning without orderId. If that param drops off the URL for any reason (user edits the URL manually, a stale link [happen this week in the project], a redirect that forgets to forward the query string), strict won't catch it — there's no "invalid value" to complain about, just an absent one. Today that null silently flows into a DB query:

const { orderId } = await loadOrderParams(searchParams)
const order = await db.order.findUnique({ where: { id: orderId } })
// orderId is null here, depending on the ORM/DB this either throws a
// generic, unrelated error, or in the worst case returns unexpected data

The resulting error (if any) points at order.total being undefined three lines away, not at the actual root cause. required turns that into a clear, early failure right at the loader:

orderId: parseAsInteger.withOptions({ required: true })
// → "[nuqs] Missing required search param `orderId`"

So the two options are complementary rather than overlapping: strict = "if present, must be valid", required = "must be present at all". Happy to help if need anything

Keep the required-parser-option check alongside the strict-parsing
fix for empty queries brought in from next (47ng#1510).
@franky47

franky47 commented Aug 1, 2026

Copy link
Copy Markdown
Member

a page like /orders/detail?orderId=4821, where the page has no meaning without orderId

I'd wager your problem is a URL design one: that orderId should be part of the pathname if it's semantically required.

A good example of this is the YouTube watch page: they encode the video ID in the v search param /watch?v=dQw4w9WgXcQ, when it should really be part of the pathname: /watch/dQw4w9WgXcQ (which is the case for their link shortener: youtu.be/dQw4w9WgXcQ).

Having required and optional search params (e.g. for YouTube, v and t to start at a given point) makes it hard to maintain over time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Required option for query params

2 participants