{"id":19398978,"url":"https://github.com/vladkens/url-normalize","last_synced_at":"2025-04-24T06:31:38.188Z","repository":{"id":164978277,"uuid":"640382540","full_name":"vladkens/url-normalize","owner":"vladkens","description":"🔗🧹 Normalize URLs to a standardized form. HTTPS by default, flexible configuration, custom protocols, domain extraction, humazing URL, and punycode support. Both CJS \u0026 ESM modules available.","archived":false,"fork":false,"pushed_at":"2025-02-15T22:42:57.000Z","size":163,"stargazers_count":9,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-29T23:15:48.388Z","etag":null,"topics":["cjs","esm","normalization","normalizer","npm-package","punycode","typescript","url","url-normalization","url-normalizer"],"latest_commit_sha":null,"homepage":"https://npm.im/url-normalize","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vladkens.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/codeowners","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"vladkens","buy_me_a_coffee":"vladkens"}},"created_at":"2023-05-13T22:41:16.000Z","updated_at":"2025-02-15T22:43:01.000Z","dependencies_parsed_at":null,"dependency_job_id":"6bb6ad5d-f7af-4f0d-981e-a2cd5bed8f23","html_url":"https://github.com/vladkens/url-normalize","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladkens%2Furl-normalize","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladkens%2Furl-normalize/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladkens%2Furl-normalize/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladkens%2Furl-normalize/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vladkens","download_url":"https://codeload.github.com/vladkens/url-normalize/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250578137,"owners_count":21453250,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cjs","esm","normalization","normalizer","npm-package","punycode","typescript","url","url-normalization","url-normalizer"],"created_at":"2024-11-10T11:07:51.749Z","updated_at":"2025-04-24T06:31:38.176Z","avatar_url":"https://github.com/vladkens.png","language":"TypeScript","funding_links":["https://github.com/sponsors/vladkens","https://buymeacoffee.com/vladkens"],"categories":[],"sub_categories":[],"readme":"# url-normalize\n\n\u003cdiv align=\"center\"\u003e\n\n[\u003cimg src=\"https://badges.ws/npm/v/url-normalize\" alt=\"version\" /\u003e](https://npmjs.org/package/url-normalize)\n[\u003cimg src=\"https://badges.ws/packagephobia/publish/url-normalize\" alt=\"size\" /\u003e](https://packagephobia.now.sh/result?p=url-normalize)\n[\u003cimg src=\"https://badges.ws/npm/dm/url-normalize\" alt=\"downloads\" /\u003e](https://npmjs.org/package/url-normalize)\n[\u003cimg src=\"https://badges.ws/github/license/vladkens/url-normalize\" alt=\"license\" /\u003e](https://github.com/vladkens/url-normalize/blob/main/LICENSE)\n[\u003cimg src=\"https://badges.ws/badge/-/buy%20me%20a%20coffee/ff813f?icon=buymeacoffee\u0026label\" alt=\"donate\" /\u003e](https://buymeacoffee.com/vladkens)\n\n\u003c/div\u003e\n\n**Normalize URLs** to a standardized form. **HTTPS** by default, flexible configuration, custom protocols, **domain extraction**, **humazing URL**, and **punycode** support. Both CJS \u0026 ESM modules available.\n\n## Install\n\n```sh\nnpm i url-normalize\n```\n\n```sh\nyarn add url-normalize\n```\n\n## Usage\n\n```typescript\nimport { urlNormalize } from \"url-normalize\"\n\nurlNormalize(\"example.com\")\n// -\u003e \"https://example.com\"\n\nurlNormalize(\"//www.example.com:443/../foo/bar?b=2\u0026a=1#tag\")\n// -\u003e \"https://example.com/foo/bar?a=1\u0026b=2#tag\"\n\n// all invalid urls is null\nurlNormalize(\"example\")\n// -\u003e null\n\nurlNormalize(\"data:content/type;base64,abc\")\n// -\u003e null\n\nurlNormalize(\"tel:+123456789\")\n// -\u003e null\n\nurlNormalize(\"mailto:user@example.com\")\n// -\u003e null\n```\n\n## Configuration\n\n### defaultProtocol `(default: https)`\n\nDefault supported protocols are: `http`, `https`\n\n```typescript\nurlNormalize(\"example.com\", { defaultProtocol: \"http\" })\n// -\u003e \"http://example.com\"\n\nurlNormalize(\"example.com\", { defaultProtocol: \"ftps\" })\n// -\u003e ftps://example.com\n\n// BUT keeps original protocol if it in url\nurlNormalize(\"https://example.com\", { defaultProtocol: \"http\" })\n// -\u003e \"https://example.com\"\n```\n\n### protocol `(default: true)`\n\n```typescript\nurlNormalize(\"https://example.com\")\n// -\u003e \"https://example.com\"\n\nurlNormalize(\"https://example.com\", { protocol: false })\n// -\u003e \"example.com\"\n\nurlNormalize(\"https://example.com/foo?bar=baz\", { protocol: false })\n// -\u003e \"example.com/foo?bar=baz\"\n```\n\n### www `(default: false)`\n\n```typescript\nurlNormalize(\"www.example.com\")\n// -\u003e \"https://example.com\"\n\nurlNormalize(\"www.example.com\", { www: true })\n// -\u003e \"https://www.example.com\"\n```\n\n### auth `(default: false)`\n\n```typescript\nurlNormalize(\"https://user:pass@example.com\")\n// -\u003e \"https://example.com\"\n\nurlNormalize(\"https://user:pass@example.com\", { auth: true })\n// -\u003e \"https://user:pass@example.com\"\n```\n\n### port `(default: false)`\n\n```typescript\nurlNormalize(\"https://example.com:8080\")\n// -\u003e \"https://example.com\"\n\nurlNormalize(\"https://example.com:8080\", { port: true })\n// -\u003e \"https://example.com:8080\"\n\n// BUT for HTTP - 80 \u0026 HTTPS - 443 always without port\nurlNormalize(\"https://example.com:443\", { port: true })\n// -\u003e \"https://example.com\"\n```\n\n### index `(default: true)`\n\n```typescript\nurlNormalize(\"example.com/index.html\")\n// -\u003e \"https://example.com/index.html\"\n\nurlNormalize(\"example.com/index.html\", { index: false })\n// -\u003e \"https://example.com\"\n```\n\n### search `(default: true)`\n\n```typescript\nurlNormalize(\"example.com/?a=1\u0026b=2\")\n// -\u003e \"https://example.com/?a=1\u0026b=2\"\n\nurlNormalize(\"example.com/?a=1\u0026b=2\", { search: false })\n// -\u003e \"https://example.com\"\n```\n\n### sortSearch `(default: true)`\n\n```typescript\nurlNormalize(\"example.com/?b=2\u0026b=1\")\n// -\u003e \"https://example.com/?a=1\u0026b=2\"\n\nurlNormalize(\"example.com/?b=2\u0026b=1\", { sortSearch: false })\n// -\u003e \"https://example.com/?b=2\u0026b=1\"\n```\n\n### filterSearch\n\n```typescript\nurlNormalize(\"example.com/?c=3\u0026b=2\u0026a=1\", { filterSearch: (k, v) =\u003e k === \"a\" || v === \"3\" })\n// -\u003e https://example.com/?a=1\u0026c=3\n```\n\n### fragment `(default: true)`\n\n```typescript\nurlNormalize(\"example.com/#foo\")\n// -\u003e \"https://example.com/#foo\"\n\nurlNormalize(\"example.com/?b=2\u0026b=1\", { fragment: false })\n// -\u003e \"https://example.com\"\n```\n\n### textFragment `(default: false)`\n\n```typescript\nurlNormalize(\"example.com/#:~:text=hello\")\n// -\u003e \"https://example.com\"\n\nurlNormalize(\"example.com/?b=2\u0026b=1\", { textFragment: true })\n// -\u003e \"https://example.com/#:~:text=hello\"\n```\n\n### customProtocol `(default: false)`\n\n```typescript\nurlNormalize(\"ftps://example.com\")\n// -\u003e null\n\nurlNormalize(\"tg://example.com\")\n// -\u003e null\n\nurlNormalize(\"ftps://example.com\", { customProtocol: true })\n// -\u003e \"ftps://example.com\"\n\nurlNormalize(\"tg://example.com\", { customProtocol: true })\n// -\u003e \"tg://example.com\"\n```\n\n### forceProtocol\n\n```typescript\nurlNormalize(\"https://example.com\", { forceProtocol: \"sftp\" })\n// -\u003e \"sftp://example.com\"\n\nurlNormalize(\"tg://example.com\", { forceProtocol: \"we\" })\n// -\u003e \"we://example.com\"\n```\n\n### unicode `(default: false)`\n\n```typescript\nurlNormalize(\"👻💥.ws\")\n// -\u003e \"https://xn--9q8huc.ws\"\n\nurlNormalize(\"👻💥.ws\", { unicode: true })\n// -\u003e \"https://👻💥.ws\"\n\nurlNormalize(\"https://xn--9q8huc.ws\", { unicode: true })\n// -\u003e \"https://👻💥.ws\"\n```\n\n## Advanced\n\n### createUrlNormalize\n\n```typescript\nimport { createUrlNormalize } from \"url-normalize\"\n\nconst urlNormalize = createUrlNormalize({\n  defaultProtocol: \"http\",\n  fragment: false,\n})\n\nurlNormalize(\"example.com/foo#tag\")\n// -\u003e \"http://example.com/foo\"\n```\n\n### urlNormalizeOrFail\n\n```typescript\nimport { urlNormalize, urlNormalizeOrFail } from \"url-normalize\"\n\nurlNormalize(\"invalid\")\n// -\u003e null\n\nurlNormalizeOrFail(\"invalid\")\n// throws Exception\n```\n\n### extractDomain\n\n```typescript\nimport { extractDomain, extractDomainOrFail } from \"url-normalize\"\n\nextractDomain(\"https://example.com:8080/?a=1\u0026b=2#tag\")\n// -\u003e \"example.com\"\n\nextractDomain(\"invalid\")\n// -\u003e null\n\nextractDomainOrFail(\"invalid\")\n// throws Exception\n```\n\n### humanizeUrl\n\n```typescript\nimport { humanizeUrl, humanizeUrlOrFail } from \"url-normalize\"\n\nhumanizeUrl(\"https://example.com/foo/bar\")\n// -\u003e example.com/foo/bar\n\nhumanizeUrl(\"invalid\")\n// -\u003e null\n\nhumanizeUrlOrFail(\"invalid\")\n// throws Exception\n```\n\n## Similar projects\n\n- [sindresorhus/normalize-url](https://github.com/sindresorhus/normalize-url)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvladkens%2Furl-normalize","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvladkens%2Furl-normalize","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvladkens%2Furl-normalize/lists"}