query-string vs uri-js vs url-join vs url-parse vs url-template
前端 URL 处理工具库深度对比与选型指南
query-stringuri-jsurl-joinurl-parseurl-template类似的npm包:

前端 URL 处理工具库深度对比与选型指南

这些库解决了原生 URL API 无法覆盖的场景,包括查询参数序列化、RFC 标准合规性解析、路径拼接以及 URI 模板展开。query-string 专注于查询字符串的解析与生成;uri-js 提供严格的 RFC 3986 合规性处理;url-join 简化路径拼接;url-parse 提供轻量级的完整 URL 解析;url-template 支持 RFC 6570 标准的模板展开。开发者应根据具体需求选择,避免过度依赖单一库处理所有 URL 相关逻辑。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
query-string06,90859.1 kB21 个月前MIT
uri-js0317-306 年前BSD-2-Clause
url-join03664.74 kB6-MIT
url-parse01,03463 kB16-MIT
url-template01957.99 kB33 年前BSD-3-Clause

前端 URL 处理工具库深度对比与选型指南

在现代 Web 开发中,处理 URL 是日常任务之一。虽然浏览器提供了原生的 URLURLSearchParams API,但在复杂场景下,它们往往不够用或过于繁琐。本文对比五个主流 npm 包:query-stringuri-jsurl-joinurl-parseurl-template,帮助你在架构设计中做出正确选择。

🔍 核心功能定位:各司其职

这五个库并非直接竞争对手,而是解决了 URL 生命周期的不同环节。

query-string 专注于查询参数。

  • 主要处理 ?key=value 部分。
  • 支持嵌套对象、数组编码。
// query-string 示例
import queryString from 'query-string';

const parsed = queryString.parse('?foo=1&foo=2&bar=3');
// { foo: [1, 2], bar: '3' }

const stringified = queryString.stringify({ foo: [1, 2] });
// 'foo=1&foo=2'

uri-js 专注于标准合规性。

  • 严格遵循 RFC 3986。
  • 支持多种协议方案(http, urn, uuid 等)。
// uri-js 示例
import { parse, normalize } from 'uri-js';

const parsed = parse('http://example.com/path');
// { scheme: 'http', host: 'example.com', path: '/path' }

const normalized = normalize('HTTP://EXAMPLE.COM');
// 'http://example.com'

url-join 专注于路径拼接。

  • 自动处理斜杠 / 的重复或缺失。
  • 不解析协议或域名,仅处理路径字符串。
// url-join 示例
import urlJoin from 'url-join';

const url = urlJoin('http://example.com', '/api/', 'users', '/1');
// 'http://example.com/api/users/1'

url-parse 专注于完整结构解析。

  • 提取协议、主机、端口、查询、哈希。
  • 兼容 Node.js 和浏览器环境。
// url-parse 示例
import UrlParse from 'url-parse';

const url = new UrlParse('https://user:pass@example.com:8080/path?query#hash');
console.log(url.protocol); // 'https:'
console.log(url.hostname); // 'example.com'
console.log(url.port);     // '8080'

url-template 专注于模板展开。

  • 实现 RFC 6570 标准。
  • 将模板字符串变为实际 URL。
// url-template 示例
import urlTemplate from 'url-template';

const template = urlTemplate.parse('/users/{id}{?page,limit}');
const url = template.expand({ id: 123, page: 1, limit: 10 });
// '/users/123?page=1&limit=10'

🛠️ 场景对比:何时使用哪个库

1. 管理路由查询参数

在单页应用(SPA)中,同步 URL 状态到组件状态是常见需求。

  • query-string 是首选。它自动处理数组和对象的编码,避免手动拼接错误。
  • url-parse 也可以用,但需要额外提取 .query 属性再解析,步骤更多。
// 推荐:query-string
const params = queryString.parse(location.search);

// 备选:url-parse + 原生 API
const url = new UrlParse(location.href);
const params = new URLSearchParams(url.query);

2. 构建 API 基础路径

微前端或模块化项目中,不同模块可能贡献路径片段。

  • url-join 最安全。它确保不会出现 // 或遗漏 /
  • 原生字符串拼接 容易出错,需要大量 replace 逻辑。
// 推荐:url-join
const basePath = urlJoin(process.env.API_HOST, '/v1', endpoint);

// 不推荐:手动拼接
const basePath = `${process.env.API_HOST.replace(/\/$/, '')}/${endpoint.replace(/^\//, '')}`;

3. 验证与标准化输入

当用户输入 URL 或需要存储标准化链接时。

  • uri-js 提供最强的标准化能力。
  • 它能处理大小写规范化、编码统一化。
// 推荐:uri-js
const safeUrl = normalize(userInput);
if (safeUrl !== userInput) {
  // 提示用户 URL 已被修正
}

4. 动态 API 客户端

构建 SDK 时,接口路径往往带有参数占位符。

  • url-template 是行业标准解法。
  • 避免手动替换字符串导致的编码问题。
// 推荐:url-template
const template = parse('/repos/{owner}/{repo}');
const url = template.expand({ owner: 'npm', repo: 'cli' });

⚠️ 注意事项与潜在陷阱

原生 URL API 的冲击

现代浏览器和 Node.js 已支持原生 URL 类。对于简单场景,原生 API 足够且无需依赖。

// 原生 API 示例
const url = new URL('https://example.com/path?foo=bar');
console.log(url.searchParams.get('foo')); // 'bar'

但在以下情况,第三方库仍不可替代:

  • 需要支持旧版浏览器(原生 URL 兼容性虽好但非无限)。
  • 需要处理相对路径解析(原生 URL 必须有 base)。
  • 需要 RFC 6570 模板支持。
  • 需要更轻量的包体积(url-parse 比完整 URL polyfill 小)。

编码行为差异

不同库对空格、特殊字符的编码方式略有不同。

  • query-string 默认将空格编码为 +,符合表单提交习惯。
  • uri-js 严格遵循 RFC,可能编码为 %20
  • 混用可能导致缓存命中失败或签名验证错误。
// 编码差异示例
// query-string
stringify({ q: 'hello world' }); // 'q=hello+world'

// uri-js (serialize)
// 可能输出 'q=hello%20world' 取决于配置

📊 功能对比总结表

特性query-stringuri-jsurl-joinurl-parseurl-template
主要用途查询参数处理URI 标准化/验证路径拼接完整 URL 解析URI 模板展开
RFC 合规性实用主义严格 RFC 3986严格 RFC 6570
支持协议主要 HTTP多协议 (URN 等)无限制多协议主要 HTTP
浏览器兼容优秀优秀优秀优秀优秀
依赖复杂度极低
典型场景前端路由状态数据验证/清洗API 路径构建日志/分析解析SDK 开发

💡 架构师建议

在实际工程架构中,不要试图用一个库解决所有问题。

  1. 前端路由层:优先使用 query-string 配合框架路由(如 React Router)。它处理数组和对象最方便。
  2. 网络请求层:使用 url-join 构建基础 URL,使用 url-template 定义资源路径。这能让 API 定义更清晰。
  3. 数据验证层:如果涉及用户输入 URL 存储,使用 uri-js 进行标准化和清洗,确保数据一致性。
  4. 服务端日志:使用 url-parse 解析访问日志,它性能好且提取字段方便。

最终建议

  • 如果你的项目主要是 C 端交互页面query-string + 原生 URL 通常足够。
  • 如果你在开发 底层基础设施或 SDKuri-jsurl-template 是更专业的选择。
  • 避免重复造轮子处理斜杠拼接,url-join 虽小但能减少大量边界情况错误。

选择合适的工具能让 URL 处理逻辑更清晰 — 减少调试时间,提升代码可维护性。

如何选择: query-string vs uri-js vs url-join vs url-parse vs url-template

  • query-string:

    选择 query-string 当你需要频繁处理查询参数(query params)的解析、序列化或修改时。它完美支持数组、对象编码,且对 URL 编码细节处理得当,适合 React 或 Vue 等前端框架中的路由参数管理。

  • uri-js:

    选择 uri-js 当你需要严格的 RFC 3986 合规性,或者处理非 HTTP 协议(如 URN、UUID)时。它在验证和标准化 URI 方面表现优异,常用于 JSON Schema 验证等底层基础设施。

  • url-join:

    选择 url-join 当你只需要简单地将多个路径片段拼接成完整 URL 时。它自动处理斜杠重复或缺失的问题,代码可读性高,适合构建 API 基础路径或静态资源链接。

  • url-parse:

    选择 url-parse 当你需要在浏览器或 Node.js 环境中轻量级地解析完整 URL 结构(协议、主机、端口等)时。它比原生 URL 对象更轻量,且对相对路径处理更灵活。

  • url-template:

    选择 url-template 当你需要实现 RFC 6570 标准的 URI 模板功能时。适合构建动态 API 客户端,其中 URL 路径包含可变参数表达式,如 /users/{id}

query-string的README

query-string

Parse and stringify URL query strings

Install

npm install query-string

[!WARNING] Remember the hyphen! Do not install the deprecated querystring package!

For browser usage, this package targets the latest version of Chrome, Firefox, and Safari.

[!TIP] Consider using URLSearchParams for simple use cases. It's a native browser API that handles basic query string operations.

Usage

import queryString from 'query-string';

console.log(location.search);
//=> '?foo=bar'

const parsed = queryString.parse(location.search);
console.log(parsed);
//=> {foo: 'bar'}

console.log(location.hash);
//=> '#token=bada55cafe'

const parsedHash = queryString.parse(location.hash);
console.log(parsedHash);
//=> {token: 'bada55cafe'}

parsed.foo = 'unicorn';
parsed.ilike = 'pizza';

const stringified = queryString.stringify(parsed);
//=> 'foo=unicorn&ilike=pizza'

location.search = stringified;
// note that `location.search` automatically prepends a question mark
console.log(location.search);
//=> '?foo=unicorn&ilike=pizza'

API

.parse(string, options?)

Parse a query string into an object. Leading ? or # are ignored, so you can pass location.search or location.hash directly.

The returned object is created with Object.create(null) and thus does not have a prototype.

queryString.parse('?foo=bar');
//=> {foo: 'bar'}

queryString.parse('#token=secret&name=jhon');
//=> {token: 'secret', name: 'jhon'}

options

Type: object

decode

Type: boolean
Default: true

Decode the keys and values. URL components are decoded with decode-uri-component.

arrayFormat

Type: string
Default: 'none'

  • 'bracket': Parse arrays with bracket representation:
import queryString from 'query-string';

queryString.parse('foo[]=1&foo[]=2&foo[]=3', {arrayFormat: 'bracket'});
//=> {foo: ['1', '2', '3']}
  • 'index': Parse arrays with index representation:
import queryString from 'query-string';

queryString.parse('foo[0]=1&foo[1]=2&foo[3]=3', {arrayFormat: 'index'});
//=> {foo: ['1', '2', '3']}
  • 'comma': Parse arrays with elements separated by comma:
import queryString from 'query-string';

queryString.parse('foo=1,2,3', {arrayFormat: 'comma'});
//=> {foo: ['1', '2', '3']}
  • 'separator': Parse arrays with elements separated by a custom character:
import queryString from 'query-string';

queryString.parse('foo=1|2|3', {arrayFormat: 'separator', arrayFormatSeparator: '|'});
//=> {foo: ['1', '2', '3']}
  • 'bracket-separator': Parse arrays (that are explicitly marked with brackets) with elements separated by a custom character:
import queryString from 'query-string';

queryString.parse('foo[]', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
//=> {foo: []}

queryString.parse('foo[]=', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
//=> {foo: ['']}

queryString.parse('foo[]=1', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
//=> {foo: ['1']}

queryString.parse('foo[]=1|2|3', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
//=> {foo: ['1', '2', '3']}

queryString.parse('foo[]=1||3|||6', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
//=> {foo: ['1', '', 3, '', '', '6']}

queryString.parse('foo[]=1|2|3&bar=fluffy&baz[]=4', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
//=> {foo: ['1', '2', '3'], bar: 'fluffy', baz:['4']}
  • 'colon-list-separator': Parse arrays with parameter names that are explicitly marked with :list:
import queryString from 'query-string';

queryString.parse('foo:list=one&foo:list=two', {arrayFormat: 'colon-list-separator'});
//=> {foo: ['one', 'two']}
  • 'none': Parse arrays with elements using duplicate keys:
import queryString from 'query-string';

queryString.parse('foo=1&foo=2&foo=3');
//=> {foo: ['1', '2', '3']}
arrayFormatSeparator

Type: string
Default: ','

The character used to separate array elements when using {arrayFormat: 'separator'}.

sort

Type: Function | boolean
Default: true

Supports both Function as a custom sorting function or false to disable sorting.

parseNumbers

Type: boolean
Default: false

import queryString from 'query-string';

queryString.parse('foo=1', {parseNumbers: true});
//=> {foo: 1}

Parse the value as a number type instead of string type if it's a number.

parseBooleans

Type: boolean
Default: false

import queryString from 'query-string';

queryString.parse('foo=true', {parseBooleans: true});
//=> {foo: true}

Parse the value as a boolean type instead of string type if it's a boolean.

types

Type: object
Default: {}

Specifies a schema for parsing query values with explicit type declarations. When defined, the types provided here take precedence over general parsing options such as parseNumbers, parseBooleans, and arrayFormat.

Use this option to explicitly define the type of a specific parameter—particularly useful in cases where the type might otherwise be ambiguous (e.g., phone numbers or IDs).

You can also provide a custom function to transform the value. The function will receive the raw string and should return the desired parsed result. When used with array formats (like comma, separator, bracket, etc.), the function is applied to each array element individually.

Supported Types:

  • 'boolean': Parse flagged as a boolean (overriding the parseBooleans option):
queryString.parse('?isAdmin=true&flagged=true&isOkay=0', {
		parseBooleans: false,
		types: {
				flagged: 'boolean',
				isOkay: 'boolean',
		},
});
//=> {isAdmin: 'true', flagged: true, isOkay: false}

Note: The 'boolean' type also converts '0' and '1' to booleans, and treats valueless keys (e.g. ?flag) as true.

  • 'string': Parse phoneNumber as a string (overriding the parseNumbers option):
import queryString from 'query-string';

queryString.parse('?phoneNumber=%2B380951234567&id=1', {
	parseNumbers: true,
	types: {
		phoneNumber: 'string',
	}
});
//=> {phoneNumber: '+380951234567', id: 1}
  • 'number': Parse age as a number (even when parseNumbers is false):
import queryString from 'query-string';

queryString.parse('?age=20&id=01234&zipcode=90210', {
	types: {
		age: 'number',
	}
});
//=> {age: 20, id: '01234', zipcode: '90210'}
  • 'string[]': Parse items as an array of strings (overriding the parseNumbers option):
import queryString from 'query-string';

queryString.parse('?age=20&items=1%2C2%2C3', {
	parseNumbers: true,
	types: {
		items: 'string[]',
	}
});
//=> {age: 20, items: ['1', '2', '3']}
  • 'number[]': Parse items as an array of numbers (even when parseNumbers is false):
import queryString from 'query-string';

queryString.parse('?age=20&items=1%2C2%2C3', {
	types: {
		items: 'number[]',
	}
});
//=> {age: '20', items: [1, 2, 3]}
  • 'Function': Provide a custom function as the parameter type. The parameter's value will equal the function's return value. When used with array formats (like comma, separator, bracket, etc.), the function is applied to each array element individually.
import queryString from 'query-string';

queryString.parse('?age=20&id=01234&zipcode=90210', {
	types: {
		age: value => value * 2,
	}
});
//=> {age: 40, id: '01234', zipcode: '90210'}

// With arrays, the function is applied to each element
queryString.parse('?scores=10,20,30', {
	arrayFormat: 'comma',
	types: {
		scores: value => Number(value) * 2,
	}
});
//=> {scores: [20, 40, 60]}

NOTE: Array types (string[], number[]) are ignored if arrayFormat is set to 'none'.

queryString.parse('ids=001%2C002%2C003&foods=apple%2Corange%2Cmango', {
	arrayFormat: 'none',
	types: {
		ids: 'number[]',
		foods: 'string[]',
	},
}
//=> {ids:'001,002,003', foods:'apple,orange,mango'}
Function
import queryString from 'query-string';

queryString.parse('?age=20&id=01234&zipcode=90210', {
	types: {
		age: value => value * 2,
	}
});
//=> {age: 40, id: '01234', zipcode: '90210'}

Parse the value as a boolean type instead of string type if it's a boolean.

.stringify(object, options?)

Stringify an object into a query string and sorting the keys.

Supported value types: string, number, bigint, boolean, null, undefined, and arrays of these types. Other types like Symbol, functions, or objects (except arrays) will throw an error.

options

Type: object

strict

Type: boolean
Default: true

Strictly encode URI components. It uses encodeURIComponent if set to false. You probably don't care about this option.

encode

Type: boolean
Default: true

URL encode the keys and values.

arrayFormat

Type: string
Default: 'none'

  • 'bracket': Serialize arrays using bracket representation:
import queryString from 'query-string';

queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'bracket'});
//=> 'foo[]=1&foo[]=2&foo[]=3'
  • 'index': Serialize arrays using index representation:
import queryString from 'query-string';

queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'index'});
//=> 'foo[0]=1&foo[1]=2&foo[2]=3'
  • 'comma': Serialize arrays by separating elements with comma:
import queryString from 'query-string';

queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'comma'});
//=> 'foo=1,2,3'

queryString.stringify({foo: [1, null, '']}, {arrayFormat: 'comma'});
//=> 'foo=1,,'
// Note that typing information for null values is lost
// and `.parse('foo=1,,')` would return `{foo: [1, '', '']}`.
  • 'separator': Serialize arrays by separating elements with a custom character:
import queryString from 'query-string';

queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'separator', arrayFormatSeparator: '|'});
//=> 'foo=1|2|3'
  • 'bracket-separator': Serialize arrays by explicitly post-fixing array names with brackets and separating elements with a custom character:
import queryString from 'query-string';

queryString.stringify({foo: []}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
//=> 'foo[]'

queryString.stringify({foo: ['']}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
//=> 'foo[]='

queryString.stringify({foo: [1]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
//=> 'foo[]=1'

queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
//=> 'foo[]=1|2|3'

queryString.stringify({foo: [1, '', 3, null, null, 6]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
//=> 'foo[]=1||3|||6'

queryString.stringify({foo: [1, '', 3, null, null, 6]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|', skipNull: true});
//=> 'foo[]=1||3|6'

queryString.stringify({foo: [1, 2, 3], bar: 'fluffy', baz: [4]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
//=> 'foo[]=1|2|3&bar=fluffy&baz[]=4'
  • 'colon-list-separator': Serialize arrays with parameter names that are explicitly marked with :list:
import queryString from 'query-string';

queryString.stringify({foo: ['one', 'two']}, {arrayFormat: 'colon-list-separator'});
//=> 'foo:list=one&foo:list=two'
  • 'none': Serialize arrays by using duplicate keys:
import queryString from 'query-string';

queryString.stringify({foo: [1, 2, 3]});
//=> 'foo=1&foo=2&foo=3'
arrayFormatSeparator

Type: string
Default: ','

The character used to separate array elements when using {arrayFormat: 'separator'}.

sort

Type: Function | boolean

Supports both Function as a custom sorting function or false to disable sorting.

import queryString from 'query-string';

const order = ['c', 'a', 'b'];

queryString.stringify({a: 1, b: 2, c: 3}, {
	sort: (a, b) => order.indexOf(a) - order.indexOf(b)
});
//=> 'c=3&a=1&b=2'
import queryString from 'query-string';

queryString.stringify({b: 1, c: 2, a: 3}, {sort: false});
//=> 'b=1&c=2&a=3'

If omitted, keys are sorted using Array#sort(), which means, converting them to strings and comparing strings in Unicode code point order.

skipNull

Skip keys with null as the value.

Note that keys with undefined as the value are always skipped.

Type: boolean
Default: false

import queryString from 'query-string';

queryString.stringify({a: 1, b: undefined, c: null, d: 4}, {
	skipNull: true
});
//=> 'a=1&d=4'
import queryString from 'query-string';

queryString.stringify({a: undefined, b: null}, {
	skipNull: true
});
//=> ''
skipEmptyString

Skip keys with an empty string as the value.

Type: boolean
Default: false

import queryString from 'query-string';

queryString.stringify({a: 1, b: '', c: '', d: 4}, {
	skipEmptyString: true
});
//=> 'a=1&d=4'
import queryString from 'query-string';

queryString.stringify({a: '', b: ''}, {
	skipEmptyString: true
});
//=> ''
replacer

A function that transforms key-value pairs before stringification.

Type: function
Default: undefined

Similar to the replacer parameter of JSON.stringify(), this function is called for each key-value pair and can be used to transform values before they are stringified. The function receives the key and value, and should return the transformed value. Returning undefined will omit the key-value pair from the resulting query string.

This is useful for custom serialization of non-primitive types like Date:

import queryString from 'query-string';

queryString.stringify({
	date: new Date('2024-01-15T10:30:00Z'),
	name: 'John'
}, {
	replacer: (key, value) => {
		if (value instanceof Date) {
			return value.toISOString();
		}

		return value;
	}
});
//=> 'date=2024-01-15T10%3A30%3A00.000Z&name=John'

You can also use it to filter out keys:

import queryString from 'query-string';

queryString.stringify({
	a: 1,
	b: null,
	c: 3
}, {
	replacer: (key, value) => value === null ? undefined : value
});
//=> 'a=1&c=3'

.extract(string)

Extract a query string from a URL that can be passed into .parse().

queryString.extract('https://foo.bar?foo=bar');
//=> 'foo=bar'

.parseUrl(string, options?)

Extract the URL and the query string as an object.

Returns an object with a url and query property.

If the parseFragmentIdentifier option is true, the object will also contain a fragmentIdentifier property.

import queryString from 'query-string';

queryString.parseUrl('https://foo.bar?foo=bar');
//=> {url: 'https://foo.bar', query: {foo: 'bar'}}

queryString.parseUrl('https://foo.bar?foo=bar#xyz', {parseFragmentIdentifier: true});
//=> {url: 'https://foo.bar', query: {foo: 'bar'}, fragmentIdentifier: 'xyz'}

options

Type: object

The options are the same as for .parse().

Extra options are as below.

parseFragmentIdentifier

Parse the fragment identifier from the URL.

Type: boolean
Default: false

import queryString from 'query-string';

queryString.parseUrl('https://foo.bar?foo=bar#xyz', {parseFragmentIdentifier: true});
//=> {url: 'https://foo.bar', query: {foo: 'bar'}, fragmentIdentifier: 'xyz'}

.stringifyUrl(object, options?)

Stringify an object into a URL with a query string and sorting the keys. The inverse of .parseUrl()

The options are the same as for .stringify().

Returns a string with the URL and a query string.

Query items in the query property overrides queries in the url property.

The fragmentIdentifier property overrides the fragment identifier in the url property.

queryString.stringifyUrl({url: 'https://foo.bar', query: {foo: 'bar'}});
//=> 'https://foo.bar?foo=bar'

queryString.stringifyUrl({url: 'https://foo.bar?foo=baz', query: {foo: 'bar'}});
//=> 'https://foo.bar?foo=bar'

queryString.stringifyUrl({
	url: 'https://foo.bar',
	query: {
		top: 'foo'
	},
	fragmentIdentifier: 'bar'
});
//=> 'https://foo.bar?top=foo#bar'

object

Type: object

url

Type: string

The URL to stringify.

query

Type: object

Query items to add to the URL.

.pick(url, keys, options?)

.pick(url, filter, options?)

Pick query parameters from a URL.

Returns a string with the new URL.

import queryString from 'query-string';

queryString.pick('https://foo.bar?foo=1&bar=2#hello', ['foo']);
//=> 'https://foo.bar?foo=1#hello'

queryString.pick('https://foo.bar?foo=1&bar=2#hello', (name, value) => value === 2, {parseNumbers: true});
//=> 'https://foo.bar?bar=2#hello'

.exclude(url, keys, options?)

.exclude(url, filter, options?)

Exclude query parameters from a URL.

Returns a string with the new URL.

import queryString from 'query-string';

queryString.exclude('https://foo.bar?foo=1&bar=2#hello', ['foo']);
//=> 'https://foo.bar?bar=2#hello'

queryString.exclude('https://foo.bar?foo=1&bar=2#hello', (name, value) => value === 2, {parseNumbers: true});
//=> 'https://foo.bar?foo=1#hello'

url

Type: string

The URL containing the query parameters to filter.

keys

Type: string[]

The names of the query parameters to filter based on the function used.

filter

Type: (key, value) => boolean

A filter predicate that will be provided the name of each query parameter and its value. The parseNumbers and parseBooleans options also affect value.

options

Type: object

Parse options and stringify options.

Nesting

This module intentionally doesn't support nesting as it's not spec'd and varies between implementations, which causes a lot of edge cases.

You're much better off just converting the object to a JSON string:

import queryString from 'query-string';

queryString.stringify({
	foo: 'bar',
	nested: JSON.stringify({
		unicorn: 'cake'
	})
});
//=> 'foo=bar&nested=%7B%22unicorn%22%3A%22cake%22%7D'

However, there is support for multiple instances of the same key:

import queryString from 'query-string';

queryString.parse('likes=cake&name=bob&likes=icecream');
//=> {likes: ['cake', 'icecream'], name: 'bob'}

queryString.stringify({color: ['taupe', 'chartreuse'], id: '515'});
//=> 'color=taupe&color=chartreuse&id=515'

Falsy values

Sometimes you want to unset a key, or maybe just make it present without assigning a value to it. Here is how falsy values are stringified:

import queryString from 'query-string';

queryString.stringify({foo: false});
//=> 'foo=false'

queryString.stringify({foo: null});
//=> 'foo'

queryString.stringify({foo: undefined});
//=> ''

FAQ

Why is it parsing + as a space?

See this answer.