Skip to content

Query Params With Arrays #56

@HamishBuckmaster

Description

@HamishBuckmaster

Query params with arrays are stringified into a single comma-separated value instead of repeated keys

  • Library: better-fetch
  • Version: latest (1.1.18)
  • Environment: [Node/Browser], [runtime version], [OS]

Summary

When passing an array as a query parameter, better-fetch stringifies the array into a single comma-separated value rather than encoding repeated keys.

Example

  • Input code (simplified):
betterFetch('/path', {
  query: { status: ['active', 'paused'] },
});
  • Actual request:
/path?status=active,paused

Sometimes it even wraps in quotes depending on how it’s constructed:

/path?status='active,paused'
  • Expected request:
/path?status=active&status=paused

Why this matters

  • Many backends (including common frameworks and API gateways) expect arrays to be represented by repeated keys.
  • The current behavior can lead to incorrect filtering/parsing on the server side unless the server specifically supports comma-separated lists.

Desired behavior/options

  • Encode arrays as repeated keys by default: key=value1&key=value2
  • Optionally support configurable array formats, e.g.:
    • repeated: key=a&key=b (default)
    • comma: key=a,b
    • indices: key[0]=a&key[1]=b
    • brackets: key[]=a&key[]=b
  • Do not add quotes around values.

Workarounds tried

  • Manually building the query string with URLSearchParams:
const qs = new URLSearchParams();
['active', 'paused'].forEach((s) => qs.append('status', s));
betterFetch(`/path?${qs.toString()}`, {
  // ...
});

This works, but defeats the convenience of the built-in query option.

Steps to reproduce

  1. Use better-fetch with a query option containing an array value:
betterFetch('/path', { query: { status: ['active', 'paused'] } });
  1. Observe the resulting URL/request being made.

Expected

/path?status=active&status=paused

Actual

/path?status=active,paused

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions