安装
npm install normalize-url
yarn add normalize-url
pnpm add normalize-url
bun add normalize-url
README

normalize-url Coverage Status

Normalize a URL

Useful when you need to display, store, deduplicate, sort, compare, etc, URLs.

[!NOTE] This package does not do URL sanitization. Garbage in, garbage out. If you use this in a server context and accept URLs as user input, it's up to you to protect against invalid URLs, path traversal attacks, etc.

Install

npm install normalize-url

Usage

import normalizeUrl from 'normalize-url';

normalizeUrl('sindresorhus.com');
//=> 'http://sindresorhus.com'

normalizeUrl('//www.sindresorhus.com:80/../baz?b=bar&a=foo');
//=> 'http://sindresorhus.com/baz?a=foo&b=bar'

API

normalizeUrl(url, options?)

URLs with custom protocols are not normalized and just passed through by default. Supported protocols are: https, http, file, and data. Use the customProtocols option to add support for additional protocols.

Human-friendly URLs with basic auth (for example, user:password@sindresorhus.com) are not handled because basic auth conflicts with custom protocols. Basic auth URLs are also deprecated.

url

Type: string

URL to normalize, including data URL.

options

Type: object

defaultProtocol

Type: string
Default: 'http'
Values: 'https' | 'http'

customProtocols

Type: string[]
Default: undefined

Protocols to normalize in addition to the built-in ones (https, http, file, data).

Useful for HTTP-like custom protocols such as Electron schemes or app-specific protocols.

The protocols should be specified without :.

normalizeUrl('sindre://www.sorhus.com', {customProtocols: ['sindre']});
//=> 'sindre://sorhus.com'

normalizeUrl('sindre://www.sorhus.com/foo/', {customProtocols: ['sindre']});
//=> 'sindre://sorhus.com/foo'
normalizeProtocol

Type: boolean
Default: true

Prepend defaultProtocol to the URL if it's protocol-relative.

normalizeUrl('//sindresorhus.com');
//=> 'http://sindresorhus.com'

normalizeUrl('//sindresorhus.com', {normalizeProtocol: false});
//=> '//sindresorhus.com'
forceHttp

Type: boolean
Default: false

Normalize HTTPS to HTTP.

normalizeUrl('https://sindresorhus.com');
//=> 'https://sindresorhus.com'

normalizeUrl('https://sindresorhus.com', {forceHttp: true});
//=> 'http://sindresorhus.com'
forceHttps

Type: boolean
Default: false

Normalize HTTP to HTTPS.

normalizeUrl('http://sindresorhus.com');
//=> 'http://sindresorhus.com'

normalizeUrl('http://sindresorhus.com', {forceHttps: true});
//=> 'https://sindresorhus.com'

This option cannot be used with the forceHttp option at the same time.

stripAuthentication

Type: boolean
Default: true

Strip the authentication part of the URL.

normalizeUrl('https://user:password@sindresorhus.com');
//=> 'https://sindresorhus.com'

normalizeUrl('https://user:password@sindresorhus.com', {stripAuthentication: false});
//=> 'https://user:password@sindresorhus.com'
stripHash

Type: boolean
Default: false

Strip the hash part of the URL.

normalizeUrl('sindresorhus.com/about.html#contact');
//=> 'http://sindresorhus.com/about.html#contact'

normalizeUrl('sindresorhus.com/about.html#contact', {stripHash: true});
//=> 'http://sindresorhus.com/about.html'
stripProtocol

Type: boolean
Default: false

Remove the protocol from the URL: http://sindresorhus.comsindresorhus.com.

It will only remove https:// and http:// protocols.

normalizeUrl('https://sindresorhus.com');
//=> 'https://sindresorhus.com'

normalizeUrl('https://sindresorhus.com', {stripProtocol: true});
//=> 'sindresorhus.com'
stripTextFragment

Type: boolean
Default: true

Strip the text fragment part of the URL.

Note: The text fragment will always be removed if the stripHash option is set to true, as the hash contains the text fragment.

normalizeUrl('http://sindresorhus.com/about.html#:~:text=hello');
//=> 'http://sindresorhus.com/about.html#'

normalizeUrl('http://sindresorhus.com/about.html#section:~:text=hello');
//=> 'http://sindresorhus.com/about.html#section'

normalizeUrl('http://sindresorhus.com/about.html#:~:text=hello', {stripTextFragment: false});
//=> 'http://sindresorhus.com/about.html#:~:text=hello'

normalizeUrl('http://sindresorhus.com/about.html#section:~:text=hello', {stripTextFragment: false});
//=> 'http://sindresorhus.com/about.html#section:~:text=hello'
stripWWW

Type: boolean
Default: true

Remove www. from the URL.

normalizeUrl('http://www.sindresorhus.com');
//=> 'http://sindresorhus.com'

normalizeUrl('http://www.sindresorhus.com', {stripWWW: false});
//=> 'http://www.sindresorhus.com'
removeQueryParameters

Type: Array<RegExp | string> | boolean
Default: [/^utm_\w+/i]

Remove query parameters that matches any of the provided strings or regexes.

Global and sticky regex flags are stripped.

normalizeUrl('www.sindresorhus.com?foo=bar&ref=test_ref', {
	removeQueryParameters: ['ref']
});
//=> 'http://sindresorhus.com/?foo=bar'

If a boolean is provided, true will remove all the query parameters.

normalizeUrl('www.sindresorhus.com?foo=bar', {
	removeQueryParameters: true
});
//=> 'http://sindresorhus.com'

false will not remove any query parameter.

normalizeUrl('www.sindresorhus.com?foo=bar&utm_medium=test&ref=test_ref', {
	removeQueryParameters: false
});
//=> 'http://www.sindresorhus.com/?foo=bar&ref=test_ref&utm_medium=test'
keepQueryParameters

Type: Array<RegExp | string>
Default: undefined

Keeps only query parameters that matches any of the provided strings or regexes.

Note: It overrides the removeQueryParameters option.

Global and sticky regex flags are stripped.

normalizeUrl('https://sindresorhus.com?foo=bar&ref=unicorn', {
	keepQueryParameters: ['ref']
});
//=> 'https://sindresorhus.com/?ref=unicorn'
removeTrailingSlash

Type: boolean
Default: true

Remove trailing slash.

Note: Trailing slash is always removed if the URL doesn't have a pathname unless the removeSingleSlash option is set to false.

normalizeUrl('http://sindresorhus.com/redirect/');
//=> 'http://sindresorhus.com/redirect'

normalizeUrl('http://sindresorhus.com/redirect/', {removeTrailingSlash: false});
//=> 'http://sindresorhus.com/redirect/'

normalizeUrl('http://sindresorhus.com/', {removeTrailingSlash: false});
//=> 'http://sindresorhus.com'
removeSingleSlash

Type: boolean
Default: true

Remove a sole / pathname in the output. This option is independent of removeTrailingSlash.

normalizeUrl('https://sindresorhus.com/');
//=> 'https://sindresorhus.com'

normalizeUrl('https://sindresorhus.com/', {removeSingleSlash: false});
//=> 'https://sindresorhus.com/'
removeDirectoryIndex

Type: boolean | Array<RegExp | string>
Default: false

Removes the default directory index file from path that matches any of the provided strings or regexes.

When true, the regex /^index\.[a-z]+$/ is used.

Global and sticky regex flags are stripped.

normalizeUrl('www.sindresorhus.com/foo/default.php', {
	removeDirectoryIndex: [/^default\.[a-z]+$/]
});
//=> 'http://sindresorhus.com/foo'
removeExplicitPort

Type: boolean
Default: false

Removes an explicit port number from the URL.

Port 443 is always removed from HTTPS URLs and 80 is always removed from HTTP URLs regardless of this option.

normalizeUrl('sindresorhus.com:123', {
	removeExplicitPort: true
});
//=> 'http://sindresorhus.com'
sortQueryParameters

Type: boolean
Default: true

Sorts the query parameters alphabetically by key.

normalizeUrl('www.sindresorhus.com?b=two&a=one&c=three', {
	sortQueryParameters: false
});
//=> 'http://sindresorhus.com/?b=two&a=one&c=three'
emptyQueryValue

Type: string
Default: 'preserve'
Values: 'preserve' | 'always' | 'never'

Controls how query parameters with empty values are formatted.

  • 'preserve' - Keep the original format (?key stays ?key, ?key= stays ?key=). If the same key appears with both formats (?a&a=), all instances will use the format without =.
  • 'always' - Always include = for empty values (?key becomes ?key=)
  • 'never' - Never include = for empty values (?key= becomes ?key)
normalizeUrl('www.sindresorhus.com?a&b=', {emptyQueryValue: 'always'});
//=> 'http://sindresorhus.com/?a=&b='

normalizeUrl('www.sindresorhus.com?a&b=', {emptyQueryValue: 'never'});
//=> 'http://sindresorhus.com/?a&b'
removePath

Type: boolean
Default: false

Removes the entire URL path, leaving only the domain.

normalizeUrl('https://example.com/path/to/page', {
	removePath: true
});
//=> 'https://example.com'
transformPath

Type: Function
Default: false

Custom function to transform the URL path components. The function receives an array of non-empty path components and should return a modified array.

// Keep only the first path component
normalizeUrl('https://example.com/api/v1/users', {
	transformPath: (pathComponents) => pathComponents.slice(0, 1)
});
//=> 'https://example.com/api'

// Remove specific components
normalizeUrl('https://example.com/admin/users', {
	transformPath: (pathComponents) => pathComponents.filter(c => c !== 'admin')
});
//=> 'https://example.com/users'
版本列表
9.0.1 2026-05-20
9.0.0 2026-02-19
8.1.1 2026-01-01
8.1.0 2025-09-10
8.0.2 2025-06-09
8.0.1 2024-03-10
8.0.0 2022-11-04
7.2.0 2022-09-27
7.1.0 2022-09-01
7.0.3 2022-01-18
7.0.2 2021-09-10
7.0.1 2021-08-11
7.0.0 2021-07-09
6.1.0 2021-06-22
6.0.1 2021-05-24
6.0.0 2021-04-07
5.3.1 2021-05-24
5.3.0 2020-10-11
5.2.1 2020-09-30
5.2.0 2020-09-28
5.1.0 2020-08-02
5.0.0 2020-01-31
4.5.1 2021-05-24
4.5.0 2019-09-29
4.4.1 2019-09-20
4.4.0 2019-09-20
4.3.0 2019-04-03
4.2.0 2019-02-28
4.1.0 2018-12-18
4.0.0 2018-11-06
3.3.0 2018-09-01
3.2.0 2018-07-10
3.1.0 2018-07-02
3.0.1 2018-05-31
3.0.0 2018-05-27
2.0.1 2017-12-25
2.0.0 2017-11-30
1.9.1 2017-03-11
1.9.0 2017-01-09
1.8.0 2016-11-08
1.7.0 2016-10-22
1.6.1 2016-09-02
1.6.0 2016-07-10
1.5.3 2016-06-07
1.5.2 2016-05-08
1.5.1 2016-05-08
1.5.0 2016-05-01
1.4.1 2016-02-18
1.4.0 2015-11-14
1.3.1 2015-09-22
1.3.0 2015-06-22
1.2.1 2015-05-19
1.2.0 2015-03-12
1.1.0 2015-03-10
1.0.2 2015-01-14
1.0.1 2015-01-13
1.0.0 2015-01-11