state-in-url 4.0.1 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -18
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -3,7 +3,8 @@ English | [한국어](./README.KO.md) | [简体中文](./README.CN.md)
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
<img src="/assets/Logo_big.png?raw=true" alt="state-in-url logo"/>
|
|
5
5
|
|
|
6
|
-
<div><h2>
|
|
6
|
+
<div><h2> Store any complex state in query parameters, URL synchronization (aka deep links) made easy. Share state between any unrelated components. With support of static types validation and server side rendering.</h2></div>
|
|
7
|
+
|
|
7
8
|
|
|
8
9
|
</div>
|
|
9
10
|
|
|
@@ -50,26 +51,38 @@ Share if it useful for you.
|
|
|
50
51
|
|
|
51
52
|
</div>
|
|
52
53
|
|
|
53
|
-
# Why use state-in-url
|
|
54
|
+
# Why use `state-in-url`?
|
|
55
|
+
|
|
56
|
+
Store any user state in query parameters; imagine JSON in a browser URL, while keeping types and structure of data.
|
|
57
|
+
Dead simple, fast, and with static Typescript validation. Deep links, aka URL synchronization, made easy.
|
|
58
|
+
|
|
59
|
+
Contains `useUrlState` hook for Next.js and react-router, and helpers for anything else on JS.
|
|
60
|
+
Since modern browsers support huge URLs and users don't care about query strings (it is a select all and copy/past workflow).
|
|
61
|
+
|
|
62
|
+
Time to use query string for state management, as it was originally intended.
|
|
63
|
+
This library does all mundane stuff for you.
|
|
54
64
|
|
|
55
|
-
|
|
65
|
+
This library is a good alternative for NUQS.
|
|
56
66
|
|
|
57
67
|
# Use cases
|
|
58
68
|
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
- 🧠 Sync data between unrelated client components
|
|
69
|
+
- 💾 Store unsaved user forms or page filters in URL
|
|
70
|
+
- 🧠 Just sync data between unrelated client components without touching URI
|
|
62
71
|
- 🔗 Shareable URLs with application state (Deep linking, URL state synchronization)
|
|
63
72
|
- 🔄 Easy state persistence across page reloads
|
|
64
73
|
|
|
65
74
|
# Features
|
|
66
75
|
|
|
67
|
-
- 🧩 **Simple**: No providers, reducers, boilerplate or new concepts, API similar to React.useState
|
|
68
|
-
- 📘 **Typescript
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
76
|
+
- 🧩 **Simple**: No providers, reducers, boilerplate or new concepts, API similar to `React.useState`
|
|
77
|
+
- 📘 **Typescript validation**: State is just an object, automatic static validation in IDE/tests according to Typescript definition
|
|
78
|
+
- ✨ **Complex data**: Nested objects, dates and arrays, works same as JSON, but in URL
|
|
79
|
+
- 🔵 **Server Side Rendering**: Can use it in Server Components, Next.js 14 and 15 are supported
|
|
80
|
+
- ⚙ **Well tested**: Unit tests and Playwright tests for Chrome/Firefox/Safari
|
|
81
|
+
- ⚡ **Fast**: Minimal rerenders, less than [1ms](https://github.com/asmyshlyaev177/state-in-url/blob/87c8c7c995c5cd7d9e7aa039c30bfe64b24abe4b/packages/urlstate/encoder/encoder.test.ts#L185) to encode and decode big object
|
|
82
|
+
- 🪶 **Lightweight**: Zero dependencies, library less than 2KB
|
|
83
|
+
- 👍 **DX**: Good developer experience, documentation, JSDoc comments, and examples
|
|
84
|
+
- ⚛️ **Framework Flexibility**: Hooks for `Next.js` and `react-router`, helpers to use it with other frameworks or pure JS
|
|
85
|
+
- 📃 **Permissive license**: MIT
|
|
73
86
|
|
|
74
87
|
## Table of content
|
|
75
88
|
|
|
@@ -113,7 +126,8 @@ Possibly need to set `"module": "ES2022"`, or `"module": "ESNext"`
|
|
|
113
126
|
|
|
114
127
|
## useUrlState
|
|
115
128
|
|
|
116
|
-
|
|
129
|
+
Main hook that takes initial state as parameter and returns state object, callback to update url, and callback to update only state.
|
|
130
|
+
All components that use the same `state` object are automatically synchronized.
|
|
117
131
|
|
|
118
132
|
## useUrlState hook for Next.js
|
|
119
133
|
|
|
@@ -125,11 +139,11 @@ Possibly need to set `"module": "ES2022"`, or `"module": "ESNext"`
|
|
|
125
139
|
|
|
126
140
|
#### Basic
|
|
127
141
|
|
|
128
|
-
1. Define state shape
|
|
142
|
+
1. Define state shape with default values
|
|
129
143
|
|
|
130
144
|
```typescript
|
|
131
145
|
// userState.ts
|
|
132
|
-
//
|
|
146
|
+
// Only parameters with value different from default will go to the url.
|
|
133
147
|
export const userState: UserState = { name: '', age: 0 }
|
|
134
148
|
|
|
135
149
|
type UserState = { name: string, age: number }
|
|
@@ -154,13 +168,13 @@ function MyComponent() {
|
|
|
154
168
|
return (
|
|
155
169
|
<div>
|
|
156
170
|
<input value={urlState.name}
|
|
157
|
-
|
|
171
|
+
// same api as React.useState, e.g. setUrl(currVal => currVal + 1)
|
|
172
|
+
onChange={(ev) => setUrl({ name: ev.target.value }) }
|
|
158
173
|
/>
|
|
159
174
|
<input value={urlState.age}
|
|
160
|
-
onChange={(ev) =>
|
|
175
|
+
onChange={(ev) => setUrl({ age: +ev.target.value }) }
|
|
161
176
|
/>
|
|
162
177
|
|
|
163
|
-
// same api as React.useState
|
|
164
178
|
<input value={urlState.name}
|
|
165
179
|
onChange={(ev) => { setState(curr => ({ ...curr, name: ev.target.value })) }}
|
|
166
180
|
// Can update state immediately but sync change to url as needed
|
|
@@ -510,6 +524,27 @@ function SettingsComponent() {
|
|
|
510
524
|
- Avoid storing sensitive information in URL parameters (SSN, API keys etc)
|
|
511
525
|
- Use this [extension](https://marketplace.visualstudio.com/items?itemName=yoavbls.pretty-ts-errors) for readable TS errors
|
|
512
526
|
|
|
527
|
+
Can create state hooks for slices of state, and reuse them across application. For example:
|
|
528
|
+
```Typescript
|
|
529
|
+
type UserState = {
|
|
530
|
+
name: string;
|
|
531
|
+
age: number;
|
|
532
|
+
other: { id: string, value: number }[]
|
|
533
|
+
};
|
|
534
|
+
const userState = {
|
|
535
|
+
name: '',
|
|
536
|
+
age: 0,
|
|
537
|
+
other: [],
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
export const useUserState = () => {
|
|
541
|
+
const { urlState, setUrl } = useUrlState({ defaultState: userState });
|
|
542
|
+
|
|
543
|
+
return { userState: urlState, setUserState: setUrl };;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
```
|
|
547
|
+
|
|
513
548
|
## Gothas
|
|
514
549
|
|
|
515
550
|
1. Can pass only serializable values, `Function`, `BigInt` or `Symbol` won't work, probably things like `ArrayBuffer` neither. Everything that can be serialized to JSON will work.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "state-in-url",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"description": "Easily share complex state objects between unrelated React components, preserve types and structure, with TS validation. Deep links and url state synchronization wthout any hasssle or boilerplate.",
|
|
5
5
|
"homepage": "https://state-in-url.dev",
|
|
6
6
|
"keywords": [
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
"useUrlState",
|
|
14
14
|
"state in url",
|
|
15
15
|
"client components communication",
|
|
16
|
-
"signals alternative",
|
|
17
16
|
"query string",
|
|
18
17
|
"search params",
|
|
19
18
|
"query params",
|
|
@@ -25,7 +24,8 @@
|
|
|
25
24
|
"reactjs",
|
|
26
25
|
"react",
|
|
27
26
|
"NextJS",
|
|
28
|
-
"Next.js"
|
|
27
|
+
"Next.js",
|
|
28
|
+
"nuqs alternative"
|
|
29
29
|
],
|
|
30
30
|
"repository": {
|
|
31
31
|
"type": "git",
|
|
@@ -122,8 +122,9 @@
|
|
|
122
122
|
"kill-next": "wireit",
|
|
123
123
|
"kill-vite": "wireit",
|
|
124
124
|
"kill": "wireit",
|
|
125
|
-
"
|
|
126
|
-
"
|
|
125
|
+
"rmdist": "rm -rf dist",
|
|
126
|
+
"cleanup": "rm -rf dist .wireit node_modules test-results playwright-report coverage-reports nyc_coverage packages/example-nextjs14/node_modules packages/example-nextjs14/.next packages/example-nextjs15/node_modules packages/example-nextjs15/.next packages/example-react/node_modules packages/example-react-router6/node_modules",
|
|
127
|
+
"reinstall": "npm run cleanup && npm install",
|
|
127
128
|
"setup": "playwright install --with-deps",
|
|
128
129
|
"prepack": "npm run build && cp package.json dist/package.json && npm run build:demo",
|
|
129
130
|
"prepare": "npx husky"
|
|
@@ -191,7 +192,7 @@
|
|
|
191
192
|
}
|
|
192
193
|
},
|
|
193
194
|
"dependencies": [
|
|
194
|
-
"
|
|
195
|
+
"rmdist"
|
|
195
196
|
]
|
|
196
197
|
},
|
|
197
198
|
"dev:router6": {
|
|
@@ -305,7 +306,7 @@
|
|
|
305
306
|
"build": {
|
|
306
307
|
"command": "rollup -c rollup.config.js --bundleConfigAsCjs",
|
|
307
308
|
"dependencies": [
|
|
308
|
-
"
|
|
309
|
+
"rmdist"
|
|
309
310
|
]
|
|
310
311
|
}
|
|
311
312
|
},
|