{"id":18947868,"url":"https://github.com/thenaubit/make-url","last_synced_at":"2025-06-23T08:33:36.297Z","repository":{"id":226018905,"uuid":"767512952","full_name":"TheNaubit/make-url","owner":"TheNaubit","description":"🪄 A tiny URL builder library for TypeScript.","archived":false,"fork":false,"pushed_at":"2024-12-23T06:50:39.000Z","size":490,"stargazers_count":4,"open_issues_count":5,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-15T06:48:08.601Z","etag":null,"topics":["builder","query-string","querystring","url","url-builder"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@nauverse/make-url","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/TheNaubit.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-03-05T12:33:55.000Z","updated_at":"2024-12-04T16:18:36.000Z","dependencies_parsed_at":"2024-03-11T20:30:43.209Z","dependency_job_id":"bcf74802-0e0e-4d65-b839-558fca4a2059","html_url":"https://github.com/TheNaubit/make-url","commit_stats":null,"previous_names":["thenaubit/make-url"],"tags_count":29,"template":false,"template_full_name":null,"purl":"pkg:github/TheNaubit/make-url","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheNaubit%2Fmake-url","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheNaubit%2Fmake-url/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheNaubit%2Fmake-url/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheNaubit%2Fmake-url/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TheNaubit","download_url":"https://codeload.github.com/TheNaubit/make-url/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheNaubit%2Fmake-url/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261445177,"owners_count":23159218,"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":["builder","query-string","querystring","url","url-builder"],"created_at":"2024-11-08T13:11:44.658Z","updated_at":"2025-06-23T08:33:31.286Z","avatar_url":"https://github.com/TheNaubit.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  🪄 make-url\n  \u003cbr\u003e\n\u003c/h1\u003e\n\n\u003ch4 align=\"center\"\u003eA tiny URL builder library for TypeScript.\u003c/h4\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/TheNaubit/make-url/actions\"\u003e\n    \u003cimg src=\"https://github.com/TheNaubit/make-url/actions/workflows/release.yml/badge.svg\"\n         alt=\"Build Status\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/@nauverse/make-url\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/@nauverse/make-url.svg?style=flat\" alt=\"npm version\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://bundlephobia.com/result?p=@nauverse/make-url\"\u003e\n    \u003cimg src=\"https://img.shields.io/bundlephobia/minzip/%40nauverse/make-url\" alt=\"minzipped size\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"#what\"\u003eWhat?\u003c/a\u003e •\n  \u003ca href=\"#why\"\u003eWhy?\u003c/a\u003e •\n  \u003ca href=\"#how\"\u003eHow?\u003c/a\u003e •\n  \u003ca href=\"#typescript\"\u003eTypeScript\u003c/a\u003e •\n  \u003ca href=\"#guide-and-examples\"\u003eGuide and examples\u003c/a\u003e •\n  \u003ca href=\"#help\"\u003eHelp\u003c/a\u003e •\n  \u003ca href=\"#contribute\"\u003eContribute\u003c/a\u003e\n\u003c/p\u003e\n\n## tl;dr\nIf you just want to try and you don't want to read this guide right now (although you should in the future if you decide to use the library), you can start quickly by:\n\n### 1. Installing the dependency:\n```bash\nnpm install --save @nauverse/make-url\n```\n\n### 2. Checking this example of use:\n~~~ts\nimport { makeURL } from \"@nauverse/make-url\";\n\nmakeURL(\"https://api.example.com/\", \"/:id/:param2/:id///\", {\n  params: {\n    id: 1,\n    param2: \"678\"\n  }\n});\n// https://api.example.com/1/678/1\n~~~\n\u003e I added too many slashes intentionally to showcase they can be removed automatically (you also have an option to disable that)\n\nIf you want to see more examples, jump to [here](#full-examples).\n\n### 3. You are done! 🪄\nFeel free to test and explore and if later on you need more guidance, read the whole guide and ask in the GitHub repo.\n\n## What?\n\n*make-url* is heavily inspired in the awesome [urlcat](https://www.npmjs.com/package/urlcat). It is a tiny JavaScript library that makes building URLs very convenient and prevents common mistakes. It is fully type-safe and highly configurable.\n\n\u003cbr\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/balazsbotond/urlcat/d5834df094b4e436ebf3ba3bf015857798f29675/docs/urlcat-basic-usage.svg#gh-light-mode-only\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/balazsbotond/urlcat/d5834df094b4e436ebf3ba3bf015857798f29675/docs/urlcat-basic-usage-dark.svg#gh-dark-mode-only\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n\u003ci\u003eAlthough the image above is from the `urlcat` package, this package behaves very similar so it is a good way to showcase its functionality\u003c/i\u003e\n\u003c/p\u003e\n\n### Features\n\n  \u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003e\u003cstrong\u003ev1\u003c/strong\u003e\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e0️⃣ ‎ Zero dependencies\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e👌 1kB \u003ca href=\"https://bundlephobia.com/package/@nauverse/make-url@latest\"\u003eminified and gzipped\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e🔒 Reliable. Even when you pass really messed up strings, it finds a way to build a valid URL (just check the tests for some examples)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e✍️ TypeScript types provided\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e🛟 Safe escaping everywhere\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e🧠 Smart concatenating\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e❓ Support for query parameters (add them in any format and they will be safely escaped and added)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e#️⃣ ‎ Support for hash parameter\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e🤓 Smart trailing slash handling (and fully configurable)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e🌍 Global default config option (if you use always the same settings, you can make it constant, instead of having to specify them on each function call)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e🔗 URL type detection (if it is a full URL, a relative URL, an absolute URL...)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e🚔 Protocol enforcing settings (plus a smart mode so it handles it for you)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e🎛️ Enable or disable removing extra slashes (so it supports RFC 3986)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e📋 Query parameters support arrays, with three modes: stringify, repeat key and comma-separated\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e🧘 It also supports the relative protocol (`//example.com/my-page`)\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e✅ Production ready\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n  \u003c/table\u003e\n\n## Why?\n\nWhen a dev wants to call an API or build an URL, they must make sure to check lots of things: adding parameters in the URL path, adding query parameters, maybe adding hash parameters, making sure it is a valid URL, mayberemoving trailing slashes and much, much more:\n\n~~~js\nconst API_URL = 'https://api.example.com/';\n\nfunction getUserPosts(id, blogId, limit, offset) {\n  const requestUrl = `${API_URL}/users/${id}/blogs/${blogId}/posts?limit=${limit}\u0026offset=${offset}`;\n  // send HTTP request\n}\n~~~\n\nAs you can see, this minimal example is already rather hard to read. It is also incorrect:\n\n- I forgot that there was a trailing slash at the end of the `API_URL` constant so this resulted in a URL containing duplicate slashes (`https://api.example.com//users`).\n- The embedded values need to be escaped using `encodeURIComponent`\n\nI can use the built-in `URL` class to prevent duplicate slashes and `URLSearchParams` to escape the query string. But I still need to escape all path parameters manually.\n\n~~~js\nconst API_URL = 'https://api.example.com/';\n\nfunction getUserPosts(id, blogId, limit, offset) {\n  const escapedId = encodeURIComponent(id);\n  const escapedBlogId = encodeURIComponent(blogId);\n  const path = `/users/${escapedId}/blogs/${escapedBlogId}`;\n  const url = new URL(path, API_URL);\n  url.search = new URLSearchParams({ limit, offset });\n  const requestUrl = url.href;\n  // send HTTP request\n}\n~~~\n\nSomething like that should be an easy task, but it can be a real pain. That is why this library exists.\n\nAnd you might wonder: why, if you are inspired in `urlcat`, don't just use that library?\n\nWell, that library allows you to generate complete URLs with some protections but... it was not enough safe for me (and I also needed to support other URL formats like relative URLs).\n\n~~~js\nconst API_URL = 'https://api.example.com/';\nconst SOME_SLUG = 'hey';\n\nfunction getUserPosts(id, limit, offset) {\n  const requestUrl = makeURL('api.example.com', SOME_SLUG, 'users/:id/posts', {\n      params: { \n        id,\n        limit,\n        offset \n      }\n    });\n  // The URL will be:\n  // https://api.example.com/hey/users/\u003cid_value\u003e/?limit=\u003climit_value\u003e\u0026offset=\u003coffset_value\u003e\n  // send HTTP request\n}\n~~~\n\n## How?\n\n### Install\n\nCurrently, the package is distributed via NPM.\n\n```bash\nnpm install --save @nauverse/make-url\n```\n\n### Usage with Node\n\nNode 18 and above are officially supported, though you may have luck using it with an earlier Node version.\nSince the code uses the `URL` and `URLSearchParams` classes internally, which aren't available below Node v10, the library is known not to work with those versions.\n\nThe package comes with CJS and ESM modules.\n\n## TypeScript\n\nThis library provides its own type definitions. \"It just works\", no need to install anything from `@types`.\n\n## Guide and examples\n\u003e A good contribution for this repo would be a more detailed guide about how to use it.\n\nThe most important function that this package offers is `makeURL`.\nYou can call with with any amount of string values and optionally at the end with a config object.\n\nA config object has the following interface:\n~~~ts\nexport interface IParams {\n  params: Record\u003cstring, unknown\u003e;\n  hash: string;\n  config: {\n    forceProtocol: \"http\" | \"https\" | \"none\" | \"auto\" | \"auto-insecure\";\n    trailingSlash: \"add\" | \"remove\";\n    strict: boolean;\n    allowEmptyPathSegments: boolean;\n    arraySerializer: \"stringify\" | \"repeat\" | \"comma\";\n  };\n}\n~~~\nEvery field in the object is optional.\n\n`params` is an optional object that contains key-value pairs. If in the generated URL is there any match of `:\u003ckey\u003e`, being `\u003ckey\u003e` any of the keys in that object, the matches will be replaced with the value of their respective keys.\nIf they are not replaced in the URL, they will be added to the URL as query parameters.\n\nLet's see some examples:\n### makeURL with only query parameters\n~~~ts\nmakeURL(\"https://example.com\", {\n  params: {\n    id: 12,\n    name: \"test\"\n  }\n});\n// https://example.com?id=12\u0026name=test\n~~~\n\n### makeURL with query parameters and also URL params\n~~~ts\nmakeURL(\"https://example.com\", \":id/\", {\n  params: {\n    id: 12,\n    name: \"test\"\n  }\n});\n// https://example.com/12?name=test\n~~~\n\n\u003e Notice that the `params` values can be of any type. I used in the examples `string` and `number` types, but you can use anything (including objects) and it will be always safely casted. Don't worry if the string contains invalid characters, everything is safely encoded in this library!\n\n---\n\n`hash` is another optional field containg a string.\n\u003e  Don't worry if the string contains invalid characters, everything is safely encoded in this library!\n\nLet's see one example:\n### makeURL with a hash parameter\n~~~ts\nmakeURL(\"https://example.com\", {\n  hash: \"test\"\n});\n// https://example.com#test\n~~~\n\n---\n\nNow it is time to talk about the `config` object.\n### `allowEmptyPathSegments`\n\u003e By default, it is set to `false`\n\nThis setting is made to support the RFC 3986. That RFC allows empty path segments in URLs (for example, https://example.com//users////2).\n\nBy default, this library has this option disabled but you can enable it in any function call you need it or globally by using the `setMakeURLDefaultConfig` function.\n\nSome examples:\n#### makeURL with `allowEmptyPathSegments: true`\n~~~ts\nmakeURL(\"https://example.com\", \"//test///a\", {\n  config: {\n    allowEmptyPathSegments: true\n  }\n});\n// https://example.com//test///a\n~~~\n\n#### makeURL with `allowEmptyPathSegments: false`\n~~~ts\nmakeURL(\"https://example.com\", \"//test///a\", {\n  config: {\n    allowEmptyPathSegments: false\n  }\n});\n// https://example.com/test/a\n~~~\n\n### `arraySerializer`\n\u003e By default, it is set to `repeat`\n\nArrays are a special kind of data, specially when sending them as query parameters to the server. There are many ways to handle them and we try to support all of them.\n\nThe default mode used is `repeat` but you can change it in any function call you need it or globally by using the `setMakeURLDefaultConfig` function.\n\nThere are three possible values: `repeat`, `comma` and `stringify`. Each of them specify how to handle the arrays. Let's see some examples:\n#### makeURL with `arraySerializer: 'repeat'`\n~~~ts\nmakeURL(\"https://example.com\", \"/test\", {\n  params: {\n    arr: ['a', 'b', 'c']\n  },\n  config: {\n    arraySerializer: 'repeat'\n  }\n});\n// https://example.com/test?arr=a\u0026arr=b\u0026arr=c\n~~~\n\n#### makeURL with `arraySerializer: 'stringify'`\n~~~ts\nmakeURL(\"https://example.com\", \"/test\", {\n  params: {\n    arr: ['a', 'b', 'c']\n  },\n  config: {\n    arraySerializer: 'repeat'\n  }\n});\n// https://example.com/test?arr=%5B%22a%22%2C%22b%22%2C%22c%22%5D\n~~~\n\n#### makeURL with `arraySerializer: 'comma'`\n~~~ts\nmakeURL(\"https://example.com\", \"/test\", {\n  params: {\n    arr: ['a', 'b', 'c']\n  },\n  config: {\n    arraySerializer: 'comma'\n  }\n});\n// https://example.com/test?arr=a%2Cb%2Cc\n~~~\n\n\u003e Important: Arrays are not supported for URL variables (no matter the `mode` you use), so they won't be replaced there but added as a query parameter. See one example below:\n#### makeURL with `arraySerializer: 'comma'` with array as URL variable\n~~~ts\nmakeURL(\"https://example.com\", \"/test/:arr\", {\n  params: {\n    arr: ['a', 'b', 'c']\n  },\n  config: {\n    arraySerializer: 'comma'\n  }\n});\n// https://example.com/test/:arr?arr=a%2Cb%2Cc \u003c- Notice that we can not replace arrays in URL variables\n~~~\n\n\n### `trailingSlash`\n\u003e By default, it is set to `add`\n\nSome servers expect trailing slashes, some does not support it. With this setting, you can configure the behaviour however you want.\n\nBy default, this library has this option set to `remove` but you can change it in any function call you need it or globally by using the `setMakeURLDefaultConfig` function.\n\nIt has two possible values: `add` and `remove`.\n\nSome examples:\n#### makeURL with `trailingSlash: 'add'`\n~~~ts\nmakeURL(\"https://example.com\", \"/test/a\", {\n  config: {\n    trailingSlash: 'add'\n  }\n});\n// https://example.com/test/a/\n~~~\n\n#### makeURL with `trailingSlash: 'remove'`\n~~~ts\nmakeURL(\"https://example.com\", \"/test/a/\", {\n  config: {\n    trailingSlash: 'remove'\n  }\n});\n// https://example.com/test/a\n~~~\n\n### `forceProtocol`\n\u003e By default, it is set to `auto`\n\nIt has 5 possible values: `http`, `https`, `none`, `auto`, `auto-insecure`.\n\n`http` will always add the `http://` to the URL if it does not contain a protocol, \u003cb\u003ewithout checking if the URL is a full URL, a relative one or an absolute one\u003c/b\u003e:\n#### makeURL with `forceProtocol: 'http'` and a full URL without protocol\n~~~ts\nmakeURL(\"example.com\", \"/test/a\", {\n  config: {\n    forceProtocol: 'http'\n  }\n});\n// http://example.com/test/a\n~~~\n\n#### makeURL with `forceProtocol: 'http'` and a full URL with protocol\n~~~ts\nmakeURL(\"https://example.com\", \"/test/a\", {\n  config: {\n    forceProtocol: 'http'\n  }\n});\n// https://example.com/test/a\n~~~\n\n#### makeURL with `forceProtocol: 'http'` and a relative URL\n~~~ts\nmakeURL(\"test/a\", {\n  config: {\n    forceProtocol: 'http'\n  }\n});\n// http://test/a\n~~~\n\n#### makeURL with `forceProtocol: 'http'` and an absolute URL\n~~~ts\nmakeURL(\"/test/a\", {\n  config: {\n    forceProtocol: 'http'\n  }\n});\n// http://test/a\n~~~\n\n\u003e This means you should only use `forceProtocol: 'http'` if you are 100% sure the URLs you will build with that function will be always full URLs. If not, you should use `auto`, `auto-insecure` or `none`.\n\n---\n\n`https` will always add the `https://` to the URL if it does not contain a protocol, \u003cb\u003ewithout checking if the URL is a full URL, a relative one or an absolute one\u003c/b\u003e:\n#### makeURL with `forceProtocol: 'https'` and a full URL without protocol\n~~~ts\nmakeURL(\"example.com\", \"/test/a\", {\n  config: {\n    forceProtocol: 'https'\n  }\n});\n// https://example.com/test/a\n~~~\n\n#### makeURL with `forceProtocol: 'https'` and a full URL with protocol\n~~~ts\nmakeURL(\"http://example.com\", \"/test/a\", {\n  config: {\n    forceProtocol: 'https'\n  }\n});\n// http://example.com/test/a\n~~~\n\n#### makeURL with `forceProtocol: 'https'` and a relative URL\n~~~ts\nmakeURL(\"test/a\", {\n  config: {\n    forceProtocol: 'https'\n  }\n});\n// https://test/a\n~~~\n\n#### makeURL with `forceProtocol: 'https'` and an absolute URL\n~~~ts\nmakeURL(\"/test/a\", {\n  config: {\n    forceProtocol: 'https'\n  }\n});\n// https://test/a\n~~~\n\n\u003e This means you should only use `forceProtocol: 'https'` if you are 100% sure the URLs you will build with that function will be always full URLs. If not, you should use `auto`, `auto-insecure` or `none`.\n\n---\n`none` will not add any protocol to the URL, no matter if it has one, it doesn't have one, it is a full URL, it is a relative URL, an absolute one...:\n#### makeURL with `forceProtocol: 'none'` and a full URL without protocol\n~~~ts\nmakeURL(\"example.com\", \"/test/a\", {\n  config: {\n    forceProtocol: 'none'\n  }\n});\n// example.com/test/a\n~~~\n\n#### makeURL with `forceProtocol: 'none'` and a full URL with protocol\n~~~ts\nmakeURL(\"https://example.com\", \"/test/a\", {\n  config: {\n    forceProtocol: 'none'\n  }\n});\n// https://example.com/test/a\n~~~\n\n#### makeURL with `forceProtocol: 'none'` and a relative URL\n~~~ts\nmakeURL(\"test/a\", {\n  config: {\n    forceProtocol: 'none'\n  }\n});\n// test/a\n~~~\n\n#### makeURL with `forceProtocol: 'none'` and an absolute URL\n~~~ts\nmakeURL(\"/test/a\", {\n  config: {\n    forceProtocol: 'none'\n  }\n});\n// /test/a\n~~~\n---\n\n`auto` is the safe and smart option. It will add the `https://` protocol if the generated URL is a full URL (containing a domain) and it doesn't have already a protocol. In any other case, it won't add anything to it. This is the recommened mode in production if you want to have something to \"set and forget\":\n#### makeURL with `forceProtocol: 'auto'` and a full URL without protocol\n~~~ts\nmakeURL(\"example.com\", \"/test/a\", {\n  config: {\n    forceProtocol: 'auto'\n  }\n});\n// https://example.com/test/a\n~~~\n\n#### makeURL with `forceProtocol: 'auto'` and a full URL with protocol\n~~~ts\nmakeURL(\"http://example.com\", \"/test/a\", {\n  config: {\n    forceProtocol: 'auto'\n  }\n});\n// http://example.com/test/a\n~~~\n\n#### makeURL with `forceProtocol: 'auto'` and a relative URL\n~~~ts\nmakeURL(\"test/a\", {\n  config: {\n    forceProtocol: 'auto'\n  }\n});\n// test/a\n~~~\n\n#### makeURL with `forceProtocol: 'auto'` and an absolute URL\n~~~ts\nmakeURL(\"/test/a\", {\n  config: {\n    forceProtocol: 'auto'\n  }\n});\n// /test/a\n~~~\n---\n\n`auto-insecure` is an alternative smart option to `auto`. It will add the `http://` protocol if the generated URL is a full URL (containing a domain) and it doesn't have already a protocol. In any other case, it won't add anything to it. \n\nIt is called `insecure` not because it is not safe to use but because it uses the `http` protocol, so I prefer to make it noticeable for the devs.\n\n#### makeURL with `forceProtocol: 'auto-insecure'` and a full URL without protocol\n~~~ts\nmakeURL(\"example.com\", \"/test/a\", {\n  config: {\n    forceProtocol: 'auto-insecure'\n  }\n});\n// http://example.com/test/a\n~~~\n\n#### makeURL with `forceProtocol: 'auto-insecure'` and a full URL with protocol\n~~~ts\nmakeURL(\"https://example.com\", \"/test/a\", {\n  config: {\n    forceProtocol: 'auto-insecure'\n  }\n});\n// https://example.com/test/a\n~~~\n\n#### makeURL with `forceProtocol: 'auto-insecure'` and a relative URL\n~~~ts\nmakeURL(\"test/a\", {\n  config: {\n    forceProtocol: 'auto-insecure'\n  }\n});\n// test/a\n~~~\n\n#### makeURL with `forceProtocol: 'auto-insecure'` and an absolute URL\n~~~ts\nmakeURL(\"/test/a\", {\n  config: {\n    forceProtocol: 'auto-insecure'\n  }\n});\n// /test/a\n~~~\n\u003e Although it is not recommended to use `http` in production; if you want to use `auto` in your local environment and you have issues with the `https`, you could use a setting like: `forceProtocol: process.env.NODE_ENV === \"production\" ? \"auto\" : \"auto-insecure\"`\n\n### `strict`\n\u003e By default, it is set to `false`\n\nIt is a boolean, so it can be `true` or `false`. I set it to `false` by default to provide the most flexible option by default.\n\nThis option enforces that the final URL string you get from calling `makeURL` is a totally valid complete URL (like `https://example.com/my/path/`). If it is not, it will throw an error, so you can catch it and handle the exception.\n\nThe drawback is that relative and absolute URLs won't work with this option set to `true`, since those URLs are not \"fully valid URLs\".\n\n#### makeURL with `strict: true` and an full URL\n~~~ts\nmakeURL(\"example.com\", \"/test/a\", {\n  config: {\n    strict: true\n  }\n});\n// https://example.com/test/a\n~~~\n\n#### makeURL with `strict: true` and an full URL without protocol\n~~~ts\nmakeURL(\"example.com\", \"/test/a\", {\n  config: {\n    strict: true,\n    forceProtocol: \"none\"\n  }\n});\n// Throws an error\n~~~\n\n#### makeURL with `strict: true` and an full URL with an invalid domain\n~~~ts\nmakeURL(\"example\", \"/test/a\", {\n  config: {\n    strict: true\n  }\n});\n// Throws an error\n~~~\n\n#### makeURL with `strict: true` and a relative URL\n~~~ts\nmakeURL(\"test/a\", {\n  config: {\n    strict: true\n  }\n});\n// Throws an error\n~~~\n\n#### makeURL with `strict: true` and an absolute URL\n~~~ts\nmakeURL(\"/test/a\", {\n  config: {\n    strict: true\n  }\n});\n// Throws an error\n~~~\n\n---\n\n#### makeURL with `strict: false` and an full URL\n~~~ts\nmakeURL(\"example.com\", \"/test/a\", {\n  config: {\n    strict: false\n  }\n});\n// https://example.com/test/a\n~~~\n\n#### makeURL with `strict: false` and an full URL without protocol\n~~~ts\nmakeURL(\"example.com\", \"/test/a\", {\n  config: {\n    strict: false,\n    forceProtocol: \"none\"\n  }\n});\n// example.com/test/a\n~~~\n\n#### makeURL with `strict: false` and an full URL with an invalid domain\n~~~ts\nmakeURL(\"example\", \"/test/a\", {\n  config: {\n    strict: false\n  }\n});\n// https://example/test/a\n~~~\n\n#### makeURL with `strict: false` and a relative URL\n~~~ts\nmakeURL(\"test/a\", {\n  config: {\n    strict: false\n  }\n});\n// test/a\n~~~\n\n#### makeURL with `strict: false` and an absolute URL\n~~~ts\nmakeURL(\"/test/a\", {\n  config: {\n    strict: false\n  }\n});\n// /test/a\n~~~\n\n\u003e So, the best and most secure option is to have `strict: true`, but that won't allow you to use relative and absolute URLs. So my advice is to keep `strict: true` globally and disable it in the function calls where you know you need to build relative and/or absolute URLs.\n\n---\n\nAs we explained, you can set the config by passing a config object as the last item in any `makeURL` call. But if you uses most of the time the same settings, you might prefer to set the config globally and only pass the config object in the `makeURL` calls when you want to override them.\n\nYou can achieve it by calling the function `setMakeURLDefaultConfig`.\n\u003e If you want to set the config globally, I recommend you to call this function the earliest you can in your project, so you have the guarantee the global config is set before you call the `makeURL` function. For example, in a Node app, you might want to call it at the beginning of your entry file. In Next.js you might want to call it in the root server layout or in the middleware (if used server-side) or in a root client layout (of used client-side).\n\nThe `setMakeURLDefaultConfig` accepts only one parameter with a partial config object (meaning you don't need to set every setting).\nFor example:\n### setMakeURLDefaultConfig setting `strict: true` globally\n~~~ts\nsetMakeURLDefaultConfig({\n  strict: true\n});\n~~~\n\n---\n\nYou probably won't ever need to get the current global config, but if you need it, there is a function you can call: `getMakeURLDefaultConfig`:\n### getMakeURLDefaultConfig\n~~~ts\ngetMakeURLDefaultConfig();\n/*\n{\n  forceProtocol: \"auto\",\n  trailingSlash: \"add\",\n  strict: false,\n  allowEmptyPathSegments: false\n}\n*/\n~~~\n\n### getMakeURLDefaultConfig after setting `strict: true` globally\n~~~ts\nsetMakeURLDefaultConfig({\n  strict: true\n});\ngetMakeURLDefaultConfig();\n/*\n{\n  forceProtocol: \"auto\",\n  trailingSlash: \"add\",\n  strict: true,\n  allowEmptyPathSegments: false\n}\n*/\n~~~\n---\n### About the relative protocol\nSometimes you might want to build URLs that use the relative protocol (`//`) so you obtain URLs like `//example.com/my/path?test=1`.\n\nLuckily, this module supports building them, just keep in mind these URLs, like the relative and the absolute ones; are \u003cb\u003enot compatible\u003c/b\u003e with `strict: true`.\n\nIf you have `strict: false`, you can do use them. Here you have some examples:\n#### makeURL with `strict: false` and a relative protocol URL\n~~~ts\nmakeURL(\"//example.com\", \"test/a\", {\n  config: {\n    strict: false\n  }\n});\n// //example.com/test/a\n~~~\n\n#### makeURL with `strict: false` and a relative protocol URL but an invalid domain\n~~~ts\nmakeURL(\"//example\", \"test/a\", {\n  config: {\n    strict: false\n  }\n});\n// /example/test/a \u003c- It is transformed to an absolute URL\n~~~\n\n#### makeURL with `strict: true` and a relative protocol URL\n~~~ts\nmakeURL(\"//example.com\", \"test/a\", {\n  config: {\n    strict: true\n  }\n});\n// Throws an error\n~~~\n\n---\n### Full examples\nTo finish with this \"guide\", I want to provide some examples combining several of the explained settings:\n#### Example 1\n~~~ts\nmakeURL(\"example.com/\", \"/test/:id///edit/\", {\n  params: {\n    id: 1,\n    name: \"John\"\n  },\n  hash: \"test\",\n  config: {\n    forceProtocol: \"auto\",\n    trailingSlash: \"remove\",\n    strict: true,\n    allowEmptyPathSegments: false\n  }\n});\n// https://example.com/test/1/edit?name=John#test\n~~~\n\n#### Example 2\n~~~ts\n// Default global settings set in the entry file\nsetMakeURLDefaultConfig({\n  forceProtocol: \"auto\",\n  trailingSlash: \"remove\",\n  strict: true,\n  allowEmptyPathSegments: false\n});\n//\n\nmakeURL(\"https://api.example.com/\", \"/:id/:param2/:id///\", {\n  params: {\n    id: 1,\n    param2: \"678\"\n  }\n});\n// https://api.example.com/1/678/1\n~~~\n\n## Help\n\nThank you for using *make-url*!\n\nIf you need any help using this library, feel free to [create a GitHub issue](https://github.com/TheNaubit/make-url/issues/new/choose), and ask your questions. I'll try to answer as quickly as possible.\n\n## Contribute\n\nContributions of any kind (pull requests, bug reports, feature requests, documentation, design) are more than welcome! If you like this project and want to help, but feel like you are stuck, feel free to contact the maintainers.\n\nOther features that we still need to implement:\n- We support ports in the URL but we need to also support username and password in the domain like:\nhttps://myusername:mypassword@domain.com\n\n### Building from source\n\nBuilding the project should be quick and easy. If it isn't, it's the maintainer's fault. Please report any problems with building in a GitHub issue.\n\nYou need to have a reasonably recent version of node.js to build *make-url*. \nTested on node version 18.0.0 and npm version 8.6.0.\n\nFirst, clone the git repository:\n\n```\ngit clone git@github.com:TheNaubit/make-url.git\n```\n\nThen switch to the newly created make-url directory and install the dependencies:\n\n```\ncd make-url\nnpm install\n```\n\nYou can then run the unit tests to verify that everything works correctly:\n\n```\nnpm run test:run\n```\n\nAnd finally, build the library:\n\n```\nnpm run build\n```\n\nThe output will appear in the `dist` directory.\n\nHappy hacking!\n\n## Contributors ✨\n\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-)\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\n\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://nauverse.com\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/22015497?v=4?s=100\" width=\"100px;\" alt=\"Al \u0026#124; Naucode\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAl \u0026#124; Naucode\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#bug-TheNaubit\" title=\"Bug reports\"\u003e🐛\u003c/a\u003e \u003ca href=\"#code-TheNaubit\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"#doc-TheNaubit\" title=\"Documentation\"\u003e📖\u003c/a\u003e \u003ca href=\"#maintenance-TheNaubit\" title=\"Maintenance\"\u003e🚧\u003c/a\u003e \u003ca href=\"#test-TheNaubit\" title=\"Tests\"\u003e⚠️\u003c/a\u003e \u003ca href=\"#infra-TheNaubit\" title=\"Infrastructure (Hosting, Build-Tools, etc)\"\u003e🚇\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthenaubit%2Fmake-url","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthenaubit%2Fmake-url","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthenaubit%2Fmake-url/lists"}