Skip to content

Commit b486dd1

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix/define-page
2 parents 6e5dc20 + 06f99fe commit b486dd1

File tree

81 files changed

+7394
-4540
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+7394
-4540
lines changed

.github/workflows/autofix.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: autofix.ci
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
paths-ignore:
8+
- 'docs/**'
9+
- 'scripts/**'
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
autofix:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v4
19+
- uses: pnpm/action-setup@v4
20+
- uses: actions/setup-node@v4
21+
with:
22+
node-version: lts/*
23+
cache: pnpm
24+
25+
- run: pnpm install --frozen-lockfile
26+
- run: pnpm run lint --write
27+
28+
- uses: autofix-ci/action@551dded8c6cc8a1054039c8bc0b8b48c51dfc6ef
29+
with:
30+
commit-message: 'style: fix code style'

.github/workflows/ci.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ jobs:
2323
- run: pnpm install --frozen-lockfile
2424
- run: pnpm run lint
2525
- run: pnpm run build
26+
- run: pnpm run -C playground build
2627

2728
test:
2829
runs-on: ${{ matrix.os }}
@@ -46,14 +47,14 @@ jobs:
4647

4748
- name: Tests with coverage
4849
if: ${{ matrix.os == 'ubuntu-latest' && matrix.node == 'lts/*' }}
49-
run: pnpm test -- --coverage
50+
run: pnpm run vitest --coverage
5051

5152
- name: Tests
5253
if: ${{ matrix.os != 'ubuntu-latest' || matrix.node != 'lts/*' }}
53-
run: pnpm test
54+
run: pnpm run vitest
5455

5556
- name: Upload coverage to Codecov
5657
if: ${{ matrix.os == 'ubuntu-latest' && matrix.node == 'lts/*' }}
57-
uses: codecov/codecov-action@v4
58+
uses: codecov/codecov-action@v5
5859
with:
5960
token: ${{ secrets.CODECOV_TOKEN }}

.github/workflows/pkg.pr.new.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Publish Any Commit
2+
3+
on:
4+
pull_request:
5+
branches: main
6+
paths-ignore:
7+
- 'docs/**'
8+
- 'playground/**'
9+
- 'examples/**'
10+
11+
push:
12+
branches:
13+
- '**'
14+
tags:
15+
- '!**'
16+
paths-ignore:
17+
- 'docs/**'
18+
- 'playground/**'
19+
- 'examples/**'
20+
21+
jobs:
22+
build:
23+
runs-on: ubuntu-latest
24+
25+
steps:
26+
- name: Checkout code
27+
uses: actions/checkout@v4
28+
with:
29+
fetch-depth: 0
30+
- uses: pnpm/action-setup@v4
31+
- uses: actions/setup-node@v4
32+
with:
33+
node-version: lts/*
34+
cache: pnpm
35+
36+
- name: Install
37+
run: pnpm install --frozen-lockfile
38+
39+
- name: Build
40+
run: pnpm build
41+
42+
- name: Release
43+
run: pnpx pkg-pr-new publish --compact --pnpm .

CHANGELOG.md

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,63 @@
1+
# [0.12.0](https://github.com/posva/unplugin-vue-router/compare/v0.11.2...v0.12.0) (2025-03-04)
2+
3+
### Bug Fixes
4+
5+
- **data-loaders:** allow nested loaders to run on invalidation ([0665635](https://github.com/posva/unplugin-vue-router/commit/0665635f78a3cbebcb676c288545e870f76a9243)), closes [#583](https://github.com/posva/unplugin-vue-router/issues/583)
6+
- unpin `unplugin` ([#592](https://github.com/posva/unplugin-vue-router/issues/592)) ([89daf52](https://github.com/posva/unplugin-vue-router/commit/89daf524bd71c01a48cc7c02021e20388666da79))
7+
8+
### Performance Improvements
9+
10+
- replace `@rollup/pluginutils` with `unplugin-utils` ([#579](https://github.com/posva/unplugin-vue-router/issues/579)) ([e83a972](https://github.com/posva/unplugin-vue-router/commit/e83a972feb2156191353dbf32411f1d6fd6f9142))
11+
12+
## [0.11.2](https://github.com/posva/unplugin-vue-router/compare/v0.11.1...v0.11.2) (2025-01-26)
13+
14+
### Features
15+
16+
- allow HMR Callback ([170df11](https://github.com/posva/unplugin-vue-router/commit/170df1187fd488b8d4eceef4fa6895a54bc711dc)), closes [#503](https://github.com/posva/unplugin-vue-router/issues/503)
17+
- fix indent in generated js for auto-routes ([b734d9a](https://github.com/posva/unplugin-vue-router/commit/b734d9a1883eef472ca38514f5d44f7f99e4f20b))
18+
19+
## [0.11.1](https://github.com/posva/unplugin-vue-router/compare/v0.11.0...v0.11.1) (2025-01-21)
20+
21+
### Bug Fixes
22+
23+
- remove empty chunks ([#575](https://github.com/posva/unplugin-vue-router/issues/575)) ([02b0e24](https://github.com/posva/unplugin-vue-router/commit/02b0e243c1866f8fb4aa0e4d33ece7eb21cb0ea9))
24+
25+
# [0.11.0](https://github.com/posva/unplugin-vue-router/compare/v0.10.9...v0.11.0) (2025-01-21)
26+
27+
### Bug Fixes
28+
29+
- resolve tree node value options ([1bf080a](https://github.com/posva/unplugin-vue-router/commit/1bf080ad81fc079a5d0d1225037ebc5c28464a2c))
30+
31+
### Features
32+
33+
- add route groups ([#549](https://github.com/posva/unplugin-vue-router/issues/549)) ([e9bbf05](https://github.com/posva/unplugin-vue-router/commit/e9bbf057fc4ae952c43b366ebdf22b2f7b531490))
34+
- **hmr:** improve Vite HMR implementation ([#502](https://github.com/posva/unplugin-vue-router/issues/502)) ([68bb979](https://github.com/posva/unplugin-vue-router/commit/68bb979d2c5706415935c763b9782cda812865dc))
35+
- **loaders:** add useIsDataLoading hook ([#559](https://github.com/posva/unplugin-vue-router/issues/559)) ([9c69f54](https://github.com/posva/unplugin-vue-router/commit/9c69f54fc4715a22e118c9ad0c5a3f73a01400a0))
36+
- mkdir if parent dir does not exists ([#516](https://github.com/posva/unplugin-vue-router/issues/516)) ([6bea24a](https://github.com/posva/unplugin-vue-router/commit/6bea24a284871b0948a33e41c63aa11ce0caed19))
37+
38+
# [0.10.9](https://github.com/posva/unplugin-vue-router/compare/v0.10.8...v0.11.0) (2024-12-04)
39+
40+
### Bug Fixes
41+
42+
- **warn**: better message ([a55bc53](https://github.com/posva/unplugin-vue-router/commit/a55bc53ffc6778781207cecf6b1c7e7efdb4de1a))
43+
- **loaders:** ensure loads when a navigation is missed ([b799598](https://github.com/posva/unplugin-vue-router/commit/b799598bde55e77cd7266f97efbe3c9e450f9b2d)), closes [#495](https://github.com/posva/unplugin-vue-router/issues/495)
44+
- **loaders:** make data possibly undefined in some cases([#506](https://github.com/posva/unplugin-vue-router/issues/506)) ([10112a0](https://github.com/posva/unplugin-vue-router/commit/10112a0309e27b8caffb1990740081d286fd84a7))
45+
- upgrade support for pinia colada 0.13.0 ([b01dce4](https://github.com/posva/unplugin-vue-router/commit/b01dce4f4cdb47e22efe9c00ea902a9f1d3316a5))
46+
47+
### Features
48+
49+
- **data-loaders:** adapt colada to support always defined data ([a1cda5d](https://github.com/posva/unplugin-vue-router/commit/a1cda5de246cc2931bb3a311c52cdc340e1bcf33))
50+
- **data-loaders:** allow `data` to always be defined ([7cf7796](https://github.com/posva/unplugin-vue-router/commit/7cf7796ca82e2589b68882bfef708c755b65c77b)), closes [#319](https://github.com/posva/unplugin-vue-router/issues/319)
51+
- **data-loaders:** allow default type for errors ([5ec4076](https://github.com/posva/unplugin-vue-router/commit/5ec4076add65bbfa62a57c2c1cb8e230c6ba3e1b))
52+
- **loaders:** nuxt temp workaround ([7763619](https://github.com/posva/unplugin-vue-router/commit/7763619deb9cbbc91e569a84a1402b1a1d7c2f48))
53+
- support vite 6 ([b1c4f6c](https://github.com/posva/unplugin-vue-router/commit/b1c4f6c16cb14cd60bce677e77b1d0cd8ef6afc9))
54+
55+
### BREAKING CHANGES
56+
57+
- **data-loaders:** The default type for `error` is now `Error`.
58+
- **data-loaders:** Based on the `options` passed to a `defineLoader()` function, the `data` will now be possibly `undefined`. This enables a more convenient typing
59+
- **data-loaders:**: The `DataLoaderPlugin` must be imported from `unplugin-vue-router/data-loaders` instead of `unplugin-vue-router/runtime`.
60+
161
## [0.10.8](https://github.com/posva/unplugin-vue-router/compare/v0.10.7...v0.10.8) (2024-09-08)
262

363
### Features
@@ -169,8 +229,8 @@ internally to represent the folder structure.
169229

170230
This patch contains the necessary fixes to allow importing the data loaders. However, they cannot be imported from `vue-router/auto` nor from `unplugin-vue-router/runtime`. Instead, they should be imported from `unplugin-vue-router/data-loaders/...`. This is needed as some of the loaders depends on extra packages that not all users have installed. At the moment, there are two data loaders
171231

172-
- `unplugin-vue-router/data-loaders/basic`: https://uvr.esm.is/data-loaders/basic/
173-
- `unplugin-vue-router/data-loaders/pinia-colada`: https://uvr.esm.is/data-loaders/colada/
232+
- `unplugin-vue-router/data-loaders/basic`: <https://uvr.esm.is/data-loaders/basic/>
233+
- `unplugin-vue-router/data-loaders/pinia-colada`: <https://uvr.esm.is/data-loaders/colada/>
174234

175235
### Bug Fixes
176236

@@ -200,7 +260,7 @@ This patch contains the necessary fixes to allow importing the data loaders. How
200260

201261
# [0.8.0](https://github.com/posva/unplugin-vue-router/compare/v0.7.0...v0.8.0) (2024-02-22)
202262

203-
Based on the feedback of the RFC, the Data Loaders have been redesigned from the ground up and are now way more flexible and powerful. As a result, if you were using the experimental data loaders, make sure to check the list of breaking changes and the new RFC at https://uvr.esm.is/rfcs/data-loaders. We are looking for early testers and feedback!
263+
Based on the feedback of the RFC, the Data Loaders have been redesigned from the ground up and are now way more flexible and powerful. As a result, if you were using the experimental data loaders, make sure to check the list of breaking changes and the new RFC at <https://uvr.esm.is/rfcs/data-loaders>. We are looking for early testers and feedback!
204264

205265
For people using the file-based routing, you now need to add `unplugin-vue-router/client` to the `types` property of your tsconfig. See [setup](https://uvr.esm.is/introduction.html#setup) for an example.
206266

@@ -260,7 +320,7 @@ For people using the file-based routing, you now need to add `unplugin-vue-route
260320
moved out of the basic loader to an extended one [pinia-colada](https://uvr.esm.is/data-loaders/colada/) and the [basic loader](https://uvr.esm.is/data-loaders/basic/)
261321
has no cache. All of the pending bugs have also been fixed.
262322
I recommend you to give the RFC examples a new read to get
263-
setup: https://uvr.esm.is/data-loaders/rfc. Most of the changes are
323+
setup: <https://uvr.esm.is/data-loaders/rfc>. Most of the changes are
264324
simplifying things by removing them.
265325
Here is a list of the breaking changes to simplify
266326
migration:
@@ -269,9 +329,9 @@ For people using the file-based routing, you now need to add `unplugin-vue-route
269329
- Manual work needed to add loaders with `HasDataLoaderMeta` has been
270330
removed. It is just no longer needed. Loaders are picked up from lazy
271331
loaded components and must otherwise be directly added to a `meta.loaders`
272-
array. See the example at https://uvr.esm.is/data-loaders/rfc.html#basic-example
332+
array. See the example at <https://uvr.esm.is/data-loaders/rfc.html#basic-example>
273333
- The function `setupDataFetchingGuard` has been replaced with a Vue
274-
Plugin. See https://uvr.esm.is/data-loaders/rfc.html#data-loader-setup
334+
Plugin. See <https://uvr.esm.is/data-loaders/rfc.html#data-loader-setup>
275335
for details.
276336
- If you were relying on `cacheTime`, use the `staleTime` option in the
277337
new [`defineColadaLoader()`](https://uvr.esm.is/rfcs/data-loaders/colada) based off [@pinia/colada](https://github.com/posva/pinia-colada)
@@ -323,7 +383,7 @@ For people using the file-based routing, you now need to add `unplugin-vue-route
323383
by adding a library that properly handles the caching. This new strategy
324384
will also enable other integrations like VueFire, Apollo, and custom
325385
ones. Keep an eye (subscribe) to the RFC for news and to discus about
326-
the future of Data Loaders: https://github.com/vuejs/rfcs/discussions/460
386+
the future of Data Loaders: <https://github.com/vuejs/rfcs/discussions/460>
327387
- since data loaders aren't meant to be awaited in script
328388
setup (they are awaited at the navigation level), they now return a
329389
promise of the raw data only, not of the UseDataLoaderReturn, to make it

client.d.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ declare module 'vue-router/auto-routes' {
99
/**
1010
* Setups hot module replacement for routes.
1111
* @param router - The router instance
12+
* @param hotUpdateCallback - Callback to be called after replacing the routes and before the navigation
1213
* @example
1314
* ```ts
1415
* import { createRouter, createWebHistory } from 'vue-router'
@@ -22,7 +23,10 @@ declare module 'vue-router/auto-routes' {
2223
* }
2324
* ```
2425
*/
25-
export function handleHotUpdate(router: Router): void
26+
export function handleHotUpdate(
27+
router: Router,
28+
hotUpdateCallback?: (newRoutes: RouteRecordRaw[]) => void
29+
): void
2630
}
2731

2832
declare module 'vue-router' {

docs/.vitepress/config.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@ import {
1111
} from './meta'
1212
import { typedRouterFile, typedRouterFileAsModule } from './twoslash-files'
1313
import { extraFiles } from './twoslash/files'
14+
import { ModuleResolutionKind } from 'typescript'
1415

1516
export default defineConfig({
1617
markdown: {
1718
codeTransformers: [
1819
transformerTwoslash({
1920
twoslashOptions: {
21+
compilerOptions: {
22+
moduleResolution: ModuleResolutionKind.Bundler,
23+
},
2024
extraFiles: {
2125
...extraFiles,
2226
'router.ts': typedRouterFileAsModule,
@@ -216,6 +220,10 @@ function sidebarDataLoaders(): SidebarGroup {
216220
text: 'Cancelling a load',
217221
link: '/data-loaders/load-cancellation',
218222
},
223+
{
224+
text: 'Nuxt',
225+
link: '/data-loaders/nuxt',
226+
},
219227
{
220228
text: 'SSR',
221229
link: '/data-loaders/ssr',

docs/data-loaders/defining-loaders.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ export const useUserData = defineBasicLoader(
178178
// ...
179179
},
180180
{
181-
lazy: !import.env.SSR, // Vite specific
181+
lazy: !import.meta.env.SSR, // Vite specific
182182
}
183183
)
184184
```

docs/data-loaders/error-handling.md

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
# Error Handling
1+
# Error handling
22

33
By default, all errors thrown in a loader are considered _unexpected errors_: they will abort the navigation, just like in a navigation guard. Because they abort the navigation, they will not appear in the `error` property of the loader. Instead, they will be intercepted by Vue Router's error handling with `router.onError()`.
44

55
However, if the loader is **not navigation-aware**, the error cannot be intercepted by Vue Router and will be kept in the `error` property of the loader. This is the case for _lazy loaders_ and [_reloading data_](./reloading-data.md).
66

7-
To be able to intercept errors in blocking loaders, we can specify a list of error classes that are considered _expected errors_. This allows blocking loader to **not abort the navigation** and instead keep the error in the `error` property of the loader and let the page locally display the error state.
7+
## Defining expected Errors
8+
9+
To be able to intercept errors in non-lazy loaders, we can specify a list of error classes that are considered _expected errors_. This allows blocking loader to **not abort the navigation** and instead keep the error in the `error` property of the loader and let the page locally display the error state.
810

911
```ts{3-10,14,18} twoslash
1012
import 'unplugin-vue-router/client'
@@ -26,6 +28,9 @@ export const useUserData = defineBasicLoader(
2628
async (to) => {
2729
throw new MyError('Something went wrong')
2830
// ...
31+
// ---cut-start---
32+
return { name: 'John' }
33+
// ---cut-end---
2934
},
3035
{
3136
errors: [MyError],
@@ -57,7 +62,59 @@ app.use(DataLoaderPlugin, {
5762
})
5863
```
5964

60-
It also accepts a function that returns a boolean to determine if the error is expected or not.
65+
Then you need to opt-in in the loader by setting the `errors` option to `true` to keep the error in the `error` property of the loader.
66+
67+
```ts{7} twoslash
68+
import 'unplugin-vue-router/client'
69+
import './typed-router.d'
70+
import { defineBasicLoader } from 'unplugin-vue-router/data-loaders/basic'
71+
// @moduleResolution: bundler
72+
// ---cut---
73+
export const useUserData = defineBasicLoader(
74+
async (to) => {
75+
throw new Error('Something went wrong')
76+
// ...
77+
// ---cut-start---
78+
return { name: 'John' }
79+
// ---cut-end---
80+
},
81+
{
82+
errors: true,
83+
}
84+
)
85+
```
86+
87+
::: details Why is `errors: true` needed?
88+
89+
One of the benefits of Data Loaders is that they ensure the `data` to be ready before the component is rendered. With expected errors, this is no longer true and `data` can be `undefined`:
90+
91+
```ts{11} twoslash
92+
import 'unplugin-vue-router/client'
93+
import './typed-router.d'
94+
import { defineBasicLoader } from 'unplugin-vue-router/data-loaders/basic'
95+
// @moduleResolution: bundler
96+
// ---cut---
97+
export const useDataWithErrors = defineBasicLoader(
98+
async (to) => {
99+
// ...
100+
// ---cut-start---
101+
return { name: 'John' }
102+
// ---cut-end---
103+
},
104+
{
105+
errors: true,
106+
}
107+
)
108+
109+
const { data } = useDataWithErrors()
110+
data.value // `data` can be `undefined`
111+
```
112+
113+
:::
114+
115+
## Custom Error handling
116+
117+
If you need more control over the error handling, you can provide a function to the `errors` option. This option is available in both the `DataLoaderPlugin` and when defining a loader.
61118

62119
```ts{3-9} twoslash
63120
import 'unplugin-vue-router/client'
@@ -79,3 +136,41 @@ app.use(DataLoaderPlugin, {
79136
},
80137
})
81138
```
139+
140+
## Handling both, local and global errors
141+
142+
TODO: this hasn't been implemented yet
143+
144+
## Error handling priority
145+
146+
When you use both, global and local error handling, the local error handling has a higher priority and will override the global error handling. This is how the local and global errors are checked:
147+
148+
- if local `errors` is `false`: abort the navigation -> `data` is not `undefined`
149+
- if local `errors` is `true`: rely on the globally defined `errors` option -> `data` is possibly `undefined`
150+
- else: rely on the local `errors` option -> `data` is possibly `undefined`
151+
152+
## TypeScript
153+
154+
You will notice that the type of `error` is `Error | null` even when you specify the `errors` option. This is because if we call the `reload()` method (meaning we are outside of a navigation), the error isn't discarded, it appears in the `error` property **without being filtered** by the `errors` option.
155+
156+
In practice, depending on how you handle the error, you will add a [type guard](https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards) inside the component responsible for displaying an error or directly in a `v-if` in the template.
157+
158+
```vue-html
159+
<template>
160+
<!-- ... -->
161+
<p v-if="isMyError(error)">{{ error.message }}</p>
162+
</template>
163+
```
164+
165+
If you want to be even stricter, you can override the default `Error` type with `unknown` (or anything else) by augmenting the `TypesConfig` interface.
166+
167+
```ts
168+
// types-extension.d.ts
169+
import 'unplugin-vue-router/data-loaders'
170+
export {}
171+
declare module 'unplugin-vue-router/data-loaders' {
172+
interface TypesConfig {
173+
Error: unknown
174+
}
175+
}
176+
```

0 commit comments

Comments
 (0)