@solidjs/router 0.8.2 → 0.8.3

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 CHANGED
@@ -30,6 +30,7 @@ It supports all of Solid's SSR methods and has Solid's transitions baked in, so
30
30
  - [useMatch](#usematch)
31
31
  - [useRoutes](#useroutes)
32
32
  - [useBeforeLeave](#usebeforeleave)
33
+ - [SPAs in Deployed Environments](#spas-in-deployed-environments)
33
34
 
34
35
  ## Getting Started
35
36
 
@@ -65,35 +66,40 @@ Solid Router allows you to configure your routes using JSX:
65
66
  1. Use the `Routes` component to specify where the routes should appear in your app.
66
67
 
67
68
  ```jsx
68
- import { Routes, Route } from "@solidjs/router"
69
+ import { Routes, Route } from "@solidjs/router";
69
70
 
70
71
  export default function App() {
71
- return <>
72
+ return (
73
+ <>
72
74
  <h1>My Site with Lots of Pages</h1>
73
- <Routes>
74
-
75
- </Routes>
75
+ <Routes></Routes>
76
76
  </>
77
+ );
77
78
  }
78
79
  ```
79
80
 
80
81
  2. Add each route using the `Route` component, specifying a path and an element or component to render when the user navigates to that path.
81
82
 
82
83
  ```jsx
83
- import { Routes, Route } from "@solidjs/router"
84
+ import { Routes, Route } from "@solidjs/router";
84
85
 
85
- import Home from "./pages/Home"
86
- import Users from "./pages/Users"
86
+ import Home from "./pages/Home";
87
+ import Users from "./pages/Users";
87
88
 
88
89
  export default function App() {
89
- return <>
90
+ return (
91
+ <>
90
92
  <h1>My Site with Lots of Pages</h1>
91
93
  <Routes>
92
94
  <Route path="/users" component={Users} />
93
95
  <Route path="/" component={Home} />
94
- <Route path="/about" element={<div>This site was made with Solid</div>} />
96
+ <Route
97
+ path="/about"
98
+ element={<div>This site was made with Solid</div>}
99
+ />
95
100
  </Routes>
96
101
  </>
102
+ );
97
103
  }
98
104
  ```
99
105
 
@@ -103,19 +109,24 @@ This way, the `Users` and `Home` components will only be loaded if you're naviga
103
109
 
104
110
  ```jsx
105
111
  import { lazy } from "solid-js";
106
- import { Routes, Route } from "@solidjs/router"
112
+ import { Routes, Route } from "@solidjs/router";
107
113
  const Users = lazy(() => import("./pages/Users"));
108
114
  const Home = lazy(() => import("./pages/Home"));
109
115
 
110
116
  export default function App() {
111
- return <>
117
+ return (
118
+ <>
112
119
  <h1>My Site with Lots of Pages</h1>
113
120
  <Routes>
114
121
  <Route path="/users" component={Users} />
115
122
  <Route path="/" component={Home} />
116
- <Route path="/about" element={<div>This site was made with Solid</div>} />
123
+ <Route
124
+ path="/about"
125
+ element={<div>This site was made with Solid</div>}
126
+ />
117
127
  </Routes>
118
128
  </>
129
+ );
119
130
  }
120
131
  ```
121
132
 
@@ -125,12 +136,13 @@ Use the `A` component to create an anchor tag that takes you to a route:
125
136
 
126
137
  ```jsx
127
138
  import { lazy } from "solid-js";
128
- import { Routes, Route, A } from "@solidjs/router"
139
+ import { Routes, Route, A } from "@solidjs/router";
129
140
  const Users = lazy(() => import("./pages/Users"));
130
141
  const Home = lazy(() => import("./pages/Home"));
131
142
 
132
143
  export default function App() {
133
- return <>
144
+ return (
145
+ <>
134
146
  <h1>My Site with Lots of Pages</h1>
135
147
  <nav>
136
148
  <A href="/about">About</A>
@@ -139,37 +151,41 @@ export default function App() {
139
151
  <Routes>
140
152
  <Route path="/users" component={Users} />
141
153
  <Route path="/" component={Home} />
142
- <Route path="/about" element={<div>This site was made with Solid</div>} />
154
+ <Route
155
+ path="/about"
156
+ element={<div>This site was made with Solid</div>}
157
+ />
143
158
  </Routes>
144
159
  </>
160
+ );
145
161
  }
146
162
  ```
147
163
 
148
164
  The `<A>` tag also has an `active` class if its href matches the current location, and `inactive` otherwise. **Note:** By default matching includes locations that are descendents (eg. href `/users` matches locations `/users` and `/users/123`), use the boolean `end` prop to prevent matching these. This is particularly useful for links to the root route `/` which would match everything.
149
165
 
150
-
151
- | prop | type | description |
152
- |----------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
153
- | href | string | The path of the route to navigate to. This will be resolved relative to the route that the link is in, but you can preface it with `/` to refer back to the root. |
154
- | noScroll | boolean | If true, turn off the default behavior of scrolling to the top of the new page |
155
- | replace | boolean | If true, don't add a new entry to the browser history. (By default, the new page will be added to the browser history, so pressing the back button will take you to the previous route.) |
156
- | state | unknown | [Push this value](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState) to the history stack when navigating | |
157
- | inactiveClass | string | The class to show when the link is inactive (when the current location doesn't match the link) |
158
- | activeClass | string | The class to show when the link is active |
159
- | end | boolean | If `true`, only considers the link to be active when the curent location matches the `href` exactly; if `false`, check if the current location _starts with_ `href` |
166
+ | prop | type | description |
167
+ | ------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
168
+ | href | string | The path of the route to navigate to. This will be resolved relative to the route that the link is in, but you can preface it with `/` to refer back to the root. |
169
+ | noScroll | boolean | If true, turn off the default behavior of scrolling to the top of the new page |
170
+ | replace | boolean | If true, don't add a new entry to the browser history. (By default, the new page will be added to the browser history, so pressing the back button will take you to the previous route.) |
171
+ | state | unknown | [Push this value](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState) to the history stack when navigating |
172
+ | inactiveClass | string | The class to show when the link is inactive (when the current location doesn't match the link) |
173
+ | activeClass | string | The class to show when the link is active |
174
+ | end | boolean | If `true`, only considers the link to be active when the curent location matches the `href` exactly; if `false`, check if the current location _starts with_ `href` |
160
175
 
161
176
  ### The Navigate Component
177
+
162
178
  Solid Router provides a `Navigate` component that works similarly to `A`, but it will _immediately_ navigate to the provided path as soon as the component is rendered. It also uses the `href` prop, but you have the additional option of passing a function to `href` that returns a path to navigate to:
163
179
 
164
180
  ```jsx
165
- function getPath ({navigate, location}) {
166
- //navigate is the result of calling useNavigate(); location is the result of calling useLocation().
167
- //You can use those to dynamically determine a path to navigate to
181
+ function getPath({ navigate, location }) {
182
+ // navigate is the result of calling useNavigate(); location is the result of calling useLocation().
183
+ // You can use those to dynamically determine a path to navigate to
168
184
  return "/some-path";
169
185
  }
170
186
 
171
- //Navigating to /redirect will redirect you to the result of getPath
172
- <Route path="/redirect" element={<Navigate href={getPath}/>}/>
187
+ // Navigating to /redirect will redirect you to the result of getPath
188
+ <Route path="/redirect" element={<Navigate href={getPath} />} />;
173
189
  ```
174
190
 
175
191
  ## Dynamic Routes
@@ -178,27 +194,38 @@ If you don't know the path ahead of time, you might want to treat part of the pa
178
194
 
179
195
  ```jsx
180
196
  import { lazy } from "solid-js";
181
- import { Routes, Route } from "@solidjs/router"
197
+ import { Routes, Route } from "@solidjs/router";
182
198
  const Users = lazy(() => import("./pages/Users"));
183
199
  const User = lazy(() => import("./pages/User"));
184
200
  const Home = lazy(() => import("./pages/Home"));
185
201
 
186
202
  export default function App() {
187
- return <>
203
+ return (
204
+ <>
188
205
  <h1>My Site with Lots of Pages</h1>
189
206
  <Routes>
190
207
  <Route path="/users" component={Users} />
191
208
  <Route path="/users/:id" component={User} />
192
209
  <Route path="/" component={Home} />
193
- <Route path="/about" element={<div>This site was made with Solid</div>} />
210
+ <Route
211
+ path="/about"
212
+ element={<div>This site was made with Solid</div>}
213
+ />
194
214
  </Routes>
195
215
  </>
216
+ );
196
217
  }
197
218
  ```
198
219
 
199
220
  The colon indicates that `id` can be any string, and as long as the URL fits that pattern, the `User` component will show.
200
221
 
201
- You can then access that `id` from within a route component with `useParams`:
222
+ You can then access that `id` from within a route component with `useParams`.
223
+
224
+ > **Note on Animation/Transitions**:
225
+ > Routes that share the same path match will be treated as the same route. If you want to force re-render you can wrap your component in a keyed `<Show>` like:
226
+ > ```js
227
+ ><Show when={params.something} keyed><MyComponent></Show>
228
+ >```
202
229
 
203
230
  ---
204
231
 
@@ -206,27 +233,33 @@ Each path parameter can be validated using a `MatchFilter`.
206
233
  This allows for more complex routing descriptions than just checking the presence of a parameter.
207
234
 
208
235
  ```tsx
209
- import {lazy} from "solid-js";
210
- import {Routes, Route} from "@solidjs/router"
211
- import type {SegmentValidators} from "./types";
236
+ import { lazy } from "solid-js";
237
+ import { Routes, Route } from "@solidjs/router";
238
+ import type { SegmentValidators } from "./types";
212
239
 
213
240
  const Users = lazy(() => import("./pages/Users"));
214
241
  const User = lazy(() => import("./pages/User"));
215
242
  const Home = lazy(() => import("./pages/Home"));
216
243
 
217
244
  const filters: MatchFilters = {
218
- parent: ['mom', 'dad'], // allow enum values
245
+ parent: ["mom", "dad"], // allow enum values
219
246
  id: /^\d+$/, // only allow numbers
220
- withHtmlExtension: (v: string) => v.length > 5 && v.endsWith('.html') // we want an `*.html` extension
221
- }
247
+ withHtmlExtension: (v: string) => v.length > 5 && v.endsWith(".html"), // we want an `*.html` extension
248
+ };
222
249
 
223
250
  export default function App() {
224
- return <>
251
+ return (
252
+ <>
225
253
  <h1>My Site with Lots of Pages</h1>
226
254
  <Routes>
227
- <Route path="/users/:parent/:id/:withHtmlExtension" component={User} matchFilters={filters}/>
255
+ <Route
256
+ path="/users/:parent/:id/:withHtmlExtension"
257
+ component={User}
258
+ matchFilters={filters}
259
+ />
228
260
  </Routes>
229
261
  </>
262
+ );
230
263
  }
231
264
  ```
232
265
 
@@ -244,11 +277,10 @@ So in this example:
244
277
  ---
245
278
 
246
279
  ```jsx
247
- //async fetching function
280
+ // async fetching function
248
281
  import { fetchUser } ...
249
282
 
250
283
  export default function User () {
251
-
252
284
  const params = useParams();
253
285
 
254
286
  const [userData] = createResource(() => params.id, fetchUser);
@@ -262,8 +294,8 @@ export default function User () {
262
294
  Parameters can be specified as optional by adding a question mark to the end of the parameter name:
263
295
 
264
296
  ```jsx
265
- //Matches stories and stories/123 but not stories/123/comments
266
- <Route path='/stories/:id?' element={<Stories/>} />
297
+ // Matches stories and stories/123 but not stories/123/comments
298
+ <Route path="/stories/:id?" element={<Stories />} />
267
299
  ```
268
300
 
269
301
  ### Wildcard Routes
@@ -271,14 +303,14 @@ Parameters can be specified as optional by adding a question mark to the end of
271
303
  `:param` lets you match an arbitrary name at that point in the path. You can use `*` to match any end of the path:
272
304
 
273
305
  ```jsx
274
- //Matches any path that begins with foo, including foo/, foo/a/, foo/a/b/c
275
- <Route path='foo/*' component={Foo}/>
306
+ // Matches any path that begins with foo, including foo/, foo/a/, foo/a/b/c
307
+ <Route path="foo/*" component={Foo} />
276
308
  ```
277
309
 
278
310
  If you want to expose the wild part of the path to the component as a parameter, you can name it:
279
311
 
280
312
  ```jsx
281
- <Route path='foo/*any' element={<div>{useParams().any}</div>}/>
313
+ <Route path="foo/*any" element={<div>{useParams().any}</div>} />
282
314
  ```
283
315
 
284
316
  Note that the wildcard token must be the last part of the path; `foo/*any/bar` won't create any routes.
@@ -288,11 +320,12 @@ Note that the wildcard token must be the last part of the path; `foo/*any/bar` w
288
320
  Routes also support defining multiple paths using an array. This allows a route to remain mounted and not rerender when switching between two or more locations that it matches:
289
321
 
290
322
  ```jsx
291
- //Navigating from login to register does not cause the Login component to re-render
292
- <Route path={["login", "register"]} component={Login}/>
323
+ // Navigating from login to register does not cause the Login component to re-render
324
+ <Route path={["login", "register"]} component={Login} />
293
325
  ```
294
326
 
295
327
  ## Data Functions
328
+
296
329
  In the [above example](#dynamic-routes), the User component is lazy-loaded and then the data is fetched. With route data functions, we can instead start fetching the data parallel to loading the route, so we can use the data as soon as possible.
297
330
 
298
331
  To do this, create a function that fetches and returns the data using `createResource`. Then pass that function to the `data` prop of the `Route` component.
@@ -304,21 +337,22 @@ import { fetchUser } ...
304
337
 
305
338
  const User = lazy(() => import("./pages/users/[id].js"));
306
339
 
307
- //Data function
340
+ // Data function
308
341
  function UserData({params, location, navigate, data}) {
309
342
  const [user] = createResource(() => params.id, fetchUser);
310
343
  return user;
311
344
  }
312
345
 
313
- //Pass it in the route definition
346
+ // Pass it in the route definition
314
347
  <Route path="/users/:id" component={User} data={UserData} />;
315
348
  ```
316
349
 
317
350
  When the route is loaded, the data function is called, and the result can be accessed by calling `useRouteData()` in the route component.
318
351
 
319
352
  ```jsx
320
- //pages/users/[id].js
321
- import { useRouteData } from '@solidjs/router';
353
+ // pages/users/[id].js
354
+ import { useRouteData } from "@solidjs/router";
355
+
322
356
  export default function User() {
323
357
  const user = useRouteData();
324
358
  return <h1>{user().name}</h1>;
@@ -327,12 +361,12 @@ export default function User() {
327
361
 
328
362
  As its only argument, the data function is passed an object that you can use to access route information:
329
363
 
330
- | key | type | description |
331
- |-----------|------------------------------------------------|-------------------------------------------------------------------------------------------------------------|
332
- | params | object | The route parameters (same value as calling `useParams()` inside the route component) |
333
- | location | `{ pathname, search, hash, query, state, key}` | An object that you can use to get more information about the path (corresponds to [`useLocation()`](#uselocation)) |
334
- | navigate | `(to: string, options?: NavigateOptions) => void` | A function that you can call to navigate to a different route instead (corresponds to [`useNavigate()`](#usenavigate)) |
335
- | data | unknown | The data returned by the [parent's](#nested-routes) data function, if any. (Data will pass through any intermediate nesting.) |
364
+ | key | type | description |
365
+ | -------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
366
+ | params | object | The route parameters (same value as calling `useParams()` inside the route component) |
367
+ | location | `{ pathname, search, hash, query, state, key}` | An object that you can use to get more information about the path (corresponds to [`useLocation()`](#uselocation)) |
368
+ | navigate | `(to: string, options?: NavigateOptions) => void` | A function that you can call to navigate to a different route instead (corresponds to [`useNavigate()`](#usenavigate)) |
369
+ | data | unknown | The data returned by the [parent's](#nested-routes) data function, if any. (Data will pass through any intermediate nesting.) |
336
370
 
337
371
  A common pattern is to export the data function that corresponds to a route in a dedicated `route.data.js` file. This way, the data function can be imported without loading anything else.
338
372
 
@@ -348,16 +382,19 @@ const User = lazy(() => import("/pages/users/[id].js"));
348
382
  ```
349
383
 
350
384
  ## Nested Routes
385
+
351
386
  The following two route definitions have the same result:
352
387
 
353
388
  ```jsx
354
389
  <Route path="/users/:id" component={User} />
355
390
  ```
391
+
356
392
  ```jsx
357
393
  <Route path="/users">
358
394
  <Route path="/:id" component={User} />
359
395
  </Route>
360
396
  ```
397
+
361
398
  `/users/:id` renders the `<User/>` component, and `/users/` is an empty route.
362
399
 
363
400
  Only leaf Route nodes (innermost `Route` components) are given a route. If you want to make the parent its own route, you have to specify it separately:
@@ -368,11 +405,11 @@ Only leaf Route nodes (innermost `Route` components) are given a route. If you w
368
405
  <Route path="/:id" component={User} />
369
406
  </Route>
370
407
 
371
- //This works
408
+ // This works
372
409
  <Route path="/users" component={Users} />
373
410
  <Route path="/users/:id" component={User} />
374
411
 
375
- //This also works
412
+ // This also works
376
413
  <Route path="/users">
377
414
  <Route path="/" component={Users} />
378
415
  <Route path="/:id" component={User} />
@@ -380,30 +417,48 @@ Only leaf Route nodes (innermost `Route` components) are given a route. If you w
380
417
  ```
381
418
 
382
419
  You can also take advantage of nesting by adding a parent element with an `<Outlet/>`.
420
+
383
421
  ```jsx
384
422
  import { Outlet } from "@solidjs/router";
385
423
 
386
- function PageWrapper () {
387
- return <div>
424
+ function PageWrapper() {
425
+ return (
426
+ <div>
388
427
  <h1> We love our users! </h1>
389
- <Outlet/>
428
+ <Outlet />
390
429
  <A href="/">Back Home</A>
391
430
  </div>
431
+ );
392
432
  }
393
433
 
394
434
  <Route path="/users" component={PageWrapper}>
395
- <Route path="/" component={Users}/>
435
+ <Route path="/" component={Users} />
396
436
  <Route path="/:id" component={User} />
397
- </Route>
437
+ </Route>;
398
438
  ```
439
+
399
440
  The routes are still configured the same, but now the route elements will appear inside the parent element where the `<Outlet/>` was declared.
400
441
 
401
442
  You can nest indefinitely - just remember that only leaf nodes will become their own routes. In this example, the only route created is `/layer1/layer2`, and it appears as three nested divs.
402
443
 
403
444
  ```jsx
404
- <Route path='/' element={<div>Onion starts here <Outlet /></div>}>
405
- <Route path='layer1' element={<div>Another layer <Outlet /></div>}>
406
- <Route path='layer2' element={<div>Innermost layer</div>}></Route>
445
+ <Route
446
+ path="/"
447
+ element={
448
+ <div>
449
+ Onion starts here <Outlet />
450
+ </div>
451
+ }
452
+ >
453
+ <Route
454
+ path="layer1"
455
+ element={
456
+ <div>
457
+ Another layer <Outlet />
458
+ </div>
459
+ }
460
+ >
461
+ <Route path="layer2" element={<div>Innermost layer</div>}></Route>
407
462
  </Route>
408
463
  </Route>
409
464
  ```
@@ -415,9 +470,11 @@ If you declare a `data` function on a parent and a child, the result of the pare
415
470
  By default, Solid Router uses `location.pathname` as route path. You can simply switch to hash mode through the `source` property on `<Router>` component.
416
471
 
417
472
  ```jsx
418
- import { Router, hashIntegration } from '@solidjs/router'
473
+ import { Router, hashIntegration } from "@solidjs/router";
419
474
 
420
- <Router source={hashIntegration()}><App /></Router>
475
+ <Router source={hashIntegration()}>
476
+ <App />
477
+ </Router>;
421
478
  ```
422
479
 
423
480
  ## Memory Mode Router
@@ -425,9 +482,11 @@ import { Router, hashIntegration } from '@solidjs/router'
425
482
  You can also use memory mode router for testing purpose.
426
483
 
427
484
  ```jsx
428
- import { Router, memoryIntegration } from '@solidjs/router'
485
+ import { Router, memoryIntegration } from "@solidjs/router";
429
486
 
430
- <Router source={memoryIntegration()}><App /></Router>
487
+ <Router source={memoryIntegration()}>
488
+ <App />
489
+ </Router>;
431
490
  ```
432
491
 
433
492
  ## Config Based Routing
@@ -442,25 +501,34 @@ import { Router, useRoutes, A } from "@solidjs/router";
442
501
  const routes = [
443
502
  {
444
503
  path: "/users",
445
- component: lazy(() => import("/pages/users.js"))
504
+ component: lazy(() => import("/pages/users.js")),
446
505
  },
447
506
  {
448
507
  path: "/users/:id",
449
508
  component: lazy(() => import("/pages/users/[id].js")),
450
509
  children: [
451
- { path: "/", component: lazy(() => import("/pages/users/[id]/index.js")) },
452
- { path: "/settings", component: lazy(() => import("/pages/users/[id]/settings.js")) },
453
- { path: "/*all", component: lazy(() => import("/pages/users/[id]/[...all].js")) }
454
- ]
510
+ {
511
+ path: "/",
512
+ component: lazy(() => import("/pages/users/[id]/index.js")),
513
+ },
514
+ {
515
+ path: "/settings",
516
+ component: lazy(() => import("/pages/users/[id]/settings.js")),
517
+ },
518
+ {
519
+ path: "/*all",
520
+ component: lazy(() => import("/pages/users/[id]/[...all].js")),
521
+ },
522
+ ],
455
523
  },
456
524
  {
457
525
  path: "/",
458
- component: lazy(() => import("/pages/index.js"))
526
+ component: lazy(() => import("/pages/index.js")),
459
527
  },
460
528
  {
461
529
  path: "/*all",
462
- component: lazy(() => import("/pages/[...all].js"))
463
- }
530
+ component: lazy(() => import("/pages/[...all].js")),
531
+ },
464
532
  ];
465
533
 
466
534
  function App() {
@@ -488,6 +556,7 @@ render(
488
556
  document.getElementById("app")
489
557
  );
490
558
  ```
559
+
491
560
  ## Router Primitives
492
561
 
493
562
  Solid Router provides a number of primitives that read off the Router and Route context.
@@ -512,7 +581,7 @@ Retrieves method to do navigation. The method accepts a path to navigate to and
512
581
  - scroll (_boolean_, default `true`): scroll to top after navigation
513
582
  - state (_any_, default `undefined`): pass custom state to `location.state`
514
583
 
515
- __Note:__ The state is serialized using the [structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) which does not support all object types.
584
+ **Note:** The state is serialized using the [structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) which does not support all object types.
516
585
 
517
586
  ```js
518
587
  const navigate = useNavigate();
@@ -544,7 +613,13 @@ const [searchParams, setSearchParams] = useSearchParams();
544
613
  return (
545
614
  <div>
546
615
  <span>Page: {searchParams.page}</span>
547
- <button onClick={() => setSearchParams({ page: (parseInt(searchParams.page) || 0) + 1 })}>Next Page</button>
616
+ <button
617
+ onClick={() =>
618
+ setSearchParams({ page: (parseInt(searchParams.page) || 0) + 1 })
619
+ }
620
+ >
621
+ Next Page
622
+ </button>
548
623
  </div>
549
624
  );
550
625
  ```
@@ -591,7 +666,7 @@ Used to define routes via a config object instead of JSX. See [Config Based Rout
591
666
 
592
667
  ### useBeforeLeave
593
668
 
594
- `useBeforeLeave` takes a function that will be called prior to leaving a route. The function will be called with:
669
+ `useBeforeLeave` takes a function that will be called prior to leaving a route. The function will be called with:
595
670
 
596
671
  - from (_Location_): current location (before change).
597
672
  - to (_string | number_}: path passed to `navigate`.
@@ -601,6 +676,7 @@ Used to define routes via a config object instead of JSX. See [Config Based Rout
601
676
  - retry (_void function_, _force?: boolean_ ): call to retry the same navigation, perhaps after confirming with the user. Pass `true` to skip running the leave handlers again (ie force navigate without confirming).
602
677
 
603
678
  Example usage:
679
+
604
680
  ```js
605
681
  useBeforeLeave((e: BeforeLeaveEventArgs) => {
606
682
  if (form.isDirty && !e.defaultPrevented) {
@@ -615,3 +691,26 @@ useBeforeLeave((e: BeforeLeaveEventArgs) => {
615
691
  }
616
692
  });
617
693
  ```
694
+
695
+ ## SPAs in Deployed Environments
696
+
697
+ When deploying applications that use a client side router that does not rely on Server Side Rendering you need to handle redirects to your index page so that loading from other URLs does not cause your CDN or Hosting to return not found for pages that aren't actually there.
698
+
699
+ Each provider has a different way of doing this. For example on Netlify you create a `_redirects` file that contains:
700
+
701
+ ```sh
702
+ /* /index.html 200
703
+ ```
704
+
705
+ On Vercel you add a rewrites section to your `vercel.json`:
706
+
707
+ ```json
708
+ {
709
+ "rewrites": [
710
+ {
711
+ "source": "/(.*)",
712
+ "destination": "/index.html"
713
+ }
714
+ ]
715
+ }
716
+ ```
@@ -28,7 +28,7 @@ export interface RoutesProps {
28
28
  children: JSX.Element;
29
29
  }
30
30
  export declare const Routes: (props: RoutesProps) => JSX.Element;
31
- export declare const useRoutes: (routes: RouteDefinition | RouteDefinition[], base?: string) => () => JSX.Element;
31
+ export declare const useRoutes: (routes: RouteDefinition | RouteDefinition[] | Readonly<RouteDefinition[]>, base?: string) => () => JSX.Element;
32
32
  export type RouteProps<S extends string> = {
33
33
  path: S | S[];
34
34
  children?: JSX.Element;
@@ -46,12 +46,12 @@ export declare const Route: <S extends string>(props: RouteProps<S>) => JSX.Elem
46
46
  export declare const Outlet: () => JSX.Element;
47
47
  export interface AnchorProps extends Omit<JSX.AnchorHTMLAttributes<HTMLAnchorElement>, "state"> {
48
48
  href: string;
49
- replace?: boolean;
50
- noScroll?: boolean;
51
- state?: unknown;
52
- inactiveClass?: string;
53
- activeClass?: string;
54
- end?: boolean;
49
+ replace?: boolean | undefined;
50
+ noScroll?: boolean | undefined;
51
+ state?: unknown | undefined;
52
+ inactiveClass?: string | undefined;
53
+ activeClass?: string | undefined;
54
+ end?: boolean | undefined;
55
55
  }
56
56
  export declare function A(props: AnchorProps): JSX.Element;
57
57
  export { A as Link, A as NavLink, AnchorProps as LinkProps, AnchorProps as NavLinkProps };
package/dist/index.js CHANGED
@@ -382,8 +382,8 @@ const useSearchParams = () => {
382
382
  const location = useLocation();
383
383
  const navigate = useNavigate();
384
384
  const setSearchParams = (params, options) => {
385
- const searchString = untrack(() => mergeSearchString(location.search, params));
386
- navigate(location.pathname + searchString + location.hash, {
385
+ const searchString = untrack(() => location.pathname + mergeSearchString(location.search, params) + location.hash);
386
+ navigate(searchString, {
387
387
  scroll: false,
388
388
  resolve: false,
389
389
  ...options
package/dist/routing.js CHANGED
@@ -40,8 +40,8 @@ export const useSearchParams = () => {
40
40
  const location = useLocation();
41
41
  const navigate = useNavigate();
42
42
  const setSearchParams = (params, options) => {
43
- const searchString = untrack(() => mergeSearchString(location.search, params));
44
- navigate(location.pathname + searchString + location.hash, {
43
+ const searchString = untrack(() => location.pathname + mergeSearchString(location.search, params) + location.hash);
44
+ navigate(searchString, {
45
45
  scroll: false,
46
46
  resolve: false,
47
47
  ...options
package/dist/types.d.ts CHANGED
@@ -34,7 +34,7 @@ export interface RouterIntegration {
34
34
  utils?: Partial<RouterUtils>;
35
35
  }
36
36
  export interface RouteDataFuncArgs<T = unknown> {
37
- data: T extends RouteDataFunc ? ReturnType<T> : T;
37
+ data: T extends RouteDataFunc<infer _, infer R> ? R : T;
38
38
  params: Params;
39
39
  location: Location;
40
40
  navigate: Navigator;
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "Ryan Turnquist"
7
7
  ],
8
8
  "license": "MIT",
9
- "version": "0.8.2",
9
+ "version": "0.8.3",
10
10
  "homepage": "https://github.com/solidjs/solid-router#readme",
11
11
  "repository": {
12
12
  "type": "git",
@@ -43,7 +43,7 @@
43
43
  "prettier": "^2.7.1",
44
44
  "rollup": "^3.7.5",
45
45
  "solid-jest": "^0.2.0",
46
- "solid-js": "^1.6.6",
46
+ "solid-js": "^1.7.9",
47
47
  "typescript": "^4.9.4"
48
48
  },
49
49
  "peerDependencies": {