An open API service indexing awesome lists of open source software.

https://github.com/ignacio-nacho-barbano/loveurl

A url builder and parser pack for handling url states in an easy way.
https://github.com/ignacio-nacho-barbano/loveurl

builder javascript love npm open-source params parser searchparams string uri url validations validator

Last synced: 9 months ago
JSON representation

A url builder and parser pack for handling url states in an easy way.

Awesome Lists containing this project

README

          

# loveUrl

A URL builder and parser pack for handling URL states the easy way.

---

### 📦 Installation

Using npm:

```bash
npm install love-url
```

Using yarn:

```bash
yarn add love-url
```

Using pnpm:

```bash
pnpm add love-url
```

---

### ⚡ TL;DR — Quick Usage

```ts
type MyParams = {
showDetails: boolean;
page: number;
tags: string[];
status: "draft" | "published" | "archived";
};

// Encode to URL
// existing params PRESERVED
// currentPath PRESERVED
const url = loveUrl({
showDetails: true,
page: 2,
tags: ["food", "travel"],
status: "published",
// This param will be removed
car: undefined,
});

// Pre-existing params ?name=bob&car=fiat%20multipla&page=1
/*
url = "/current-path?name=bob&showDetails=true&page=2&tags=_._food_._travel&status=published"
*/

// Encode to URL (existing params REMOVED)
const url = loveUrl(
{
showDetails: true,
page: 2,
tags: ["food", "travel"],
status: "published",
},
{
currentParams: null,
url: "/route-somewhere-else",
}
);

// Pre-existing params ?name=bob&page=1
/*
url = "/route-somewhere-else?showDetails=true&page=2&tags=_._food_._travel&status=published"
*/

// Decode from URL
const parsed = parseLoveUrl(
"?showDetails=true&page=2&tags=_._food_._travel&status=published"
// or window.location.search
);

/*
parsed = {
showDetails: true,
page: 2,
tags: ["food", "travel"],
status: "published"
}
*/
```

---

### 🧠 Tip

- Arrays are encoded using a custom separator: `_._`
This ensures:
- Consistent decoding even with a single item (`tags=_._design` → `["design"]`)
- Reliable parsing when array items contain commas
- Booleans and numbers are parsed and typed automatically
- Invalid values (e.g., `status=broken`) will be parsed as `strings` unless custom validation is added

---

### 🚀 Motivation

**loveUrl** aims to simplify the common headaches when building and parsing URLs with parameters in modern JavaScript projects.

---

### 🔧 Key Use Cases

#### 1. **Building dynamic URLs that preserve client-side state**

Imagine your user is at `/currentPath/example` and the current URL params are:

`fileType=photo&selectedPeriod=weekly`

Instead of manually constructing links, you can just use:

```tsx
const ExampleComponent = () => (


{/* Renders: /currentPath/example?fileType=photo&selectedOption=option1&selectedPeriod=weekly */}
Option 1

{/* Renders: /currentPath/example?fileType=photo&selectedOption=option2&selectedPeriod=weekly */}
Option 2

{/* Renders: /currentPath/example?fileType=photo&selectedPeriod=weekly */}
Clear


);
```

---

#### 2. **Building and fetching dynamic URLs for APIs**

Building parameterized API URLs manually can get messy:

```ts
type DynamicDataOptions = {
startDate?: string;
endDate?: string;
format?: "photos" | "videos";
limit: number;
};

const fetchDynamicData = (params: DynamicDataOptions) => {
let dataUrl = "https://api.my-project/files/archive";

// Prevent undefined values from appearing in the query string
for (const key in params) {
if (params[key] === undefined) {
delete params[key];
}
}

const queryString = new URLSearchParams(params).toString();
if (queryString) dataUrl += `?${queryString}`;

const req = await fetch(dataUrl);
return await req.json();
};
```

Or even worse:

```ts
const fetchDynamicData = ({
startDate,
endDate,
format,
limit,
}: DynamicDataOptions) => {
const req = await fetch(
`https://api.my-project/files/archive?startDate=${startDate}&endDate=${endDate}&format=${format}&limit=${limit}`
);

return await req.json();
};
```

**Imagine doing this with 12+ parameters 😭**

---

#### ✅ With loveUrl:

```ts
const fetchDynamicData = (params: DynamicDataOptions) => {
const req = await fetch(
loveUrl(params, { url: "https://api.my-project/files/archive" })
);

return await req.json();
};
```

Clean. Type-safe. No string interpolation errors.

---

#### 3. **Parsing URL params without the chaos**

Handling conversions manually can quickly get out of hand:

```tsx
const ComponentThatUsesParams = () => {
const params = new URLSearchParams(window.location.search);

const myBoolean = params.get("myBoolean") === "true"; // string 'false' is truthy 😬
const limit = parseInt(params.get("limit"));
const percentage = parseFloat(params.get("percentage"));
let favoriteFoods = params.get("favoriteFoods");

if (favoriteFoods?.includes(",")) {
favoriteFoods = favoriteFoods.split(",");
}

return (


My Params as an object:



{JSON.stringify({
myBoolean,
limit,
percentage,
})}


);
};
```

---

#### ✅ With loveUrl:

```tsx
const ComponentThatUsesParams = () => {
const { myBoolean, limit, percentage, favoriteFoods } = parseLoveUrl<{
myBoolean: boolean;
limit: number;
percentage: number;
favoriteFoods: string[];
}>(window.location.search);

return (


My Params as an object:



{JSON.stringify({
myBoolean,
limit,
percentage,
})}


);
};
```

Type-safe, clean, and handles all conversions for you.

---

### ❤️ Why you'll love loveUrl

- Automatically ignores `undefined` values
- Handles complex param types like arrays, numbers, and booleans
- Uses a custom array separator (`_._`) for full consistency
- Prevents messy string interpolation
- Decodes and encodes with full TypeScript support
- Deals with duplicate params gracefully
- Keeps your URLs and logic clean and reliable