@@ -26,180 +26,184 @@ import routerOptions from '#build/router.options'
2626// @ts -expect-error virtual module generated by Nuxt
2727import _routes from '#build/routes'
2828
29- export default defineNuxtPlugin ( async nuxtApp => {
30- let routerBase = useRuntimeConfig ( ) . app . baseURL
31- if ( routerOptions . hashMode && ! routerBase . includes ( '#' ) ) {
32- // allow the user to provide a `#` in the middle: `/base/#/app`
33- routerBase += '#'
34- }
29+ export default defineNuxtPlugin ( {
30+ name : 'nuxt:ionic:router' ,
31+ enforce : 'pre' ,
32+ setup ( nuxtApp ) {
33+ let routerBase = useRuntimeConfig ( ) . app . baseURL
34+ if ( routerOptions . hashMode && ! routerBase . includes ( '#' ) ) {
35+ // allow the user to provide a `#` in the middle: `/base/#/app`
36+ routerBase += '#'
37+ }
3538
36- const history =
37- routerOptions . history ?.( routerBase ) ??
38- ( process . client
39- ? routerOptions . hashMode
40- ? createWebHashHistory ( routerBase )
41- : createWebHistory ( routerBase )
42- : createMemoryHistory ( routerBase ) )
43-
44- const routes = routerOptions . routes ?.( _routes ) ?? _routes
45-
46- const initialURL = process . server
47- ? nuxtApp . ssrContext ! . url
48- : createCurrentLocation ( routerBase , window . location )
49- const router = createRouter ( {
50- ...routerOptions ,
51- history,
52- routes,
53- } )
54- nuxtApp . vueApp . use ( router )
55- const previousRoute = shallowRef ( router . currentRoute . value )
56- router . afterEach ( ( _to , from ) => {
57- previousRoute . value = from
58- } )
59-
60- Object . defineProperty ( nuxtApp . vueApp . config . globalProperties , 'previousRoute' , {
61- get : ( ) => previousRoute . value ,
62- } )
63-
64- // Allows suspending the route object until page navigation completes
65- const _route = shallowRef ( router . resolve ( initialURL ) as RouteLocation )
66- const syncCurrentRoute = ( ) => {
67- _route . value = router . currentRoute . value
68- }
69- nuxtApp . hook ( 'page:finish' , syncCurrentRoute )
70- router . afterEach ( ( to , from ) => {
71- // We won't trigger suspense if the component is reused between routes
72- // so we need to update the route manually
73- if ( to . matched [ 0 ] ?. components ?. default === from . matched [ 0 ] ?. components ?. default ) {
74- syncCurrentRoute ( )
39+ const history =
40+ routerOptions . history ?.( routerBase ) ??
41+ ( process . client
42+ ? routerOptions . hashMode
43+ ? createWebHashHistory ( routerBase )
44+ : createWebHistory ( routerBase )
45+ : createMemoryHistory ( routerBase ) )
46+
47+ const routes = routerOptions . routes ?.( _routes ) ?? _routes
48+
49+ const initialURL = process . server
50+ ? nuxtApp . ssrContext ! . url
51+ : createCurrentLocation ( routerBase , window . location )
52+ const router = createRouter ( {
53+ ...routerOptions ,
54+ history,
55+ routes,
56+ } )
57+ nuxtApp . vueApp . use ( router )
58+ const previousRoute = shallowRef ( router . currentRoute . value )
59+ router . afterEach ( ( _to , from ) => {
60+ previousRoute . value = from
61+ } )
62+
63+ Object . defineProperty ( nuxtApp . vueApp . config . globalProperties , 'previousRoute' , {
64+ get : ( ) => previousRoute . value ,
65+ } )
66+
67+ // Allows suspending the route object until page navigation completes
68+ const _route = shallowRef ( router . resolve ( initialURL ) as RouteLocation )
69+ const syncCurrentRoute = ( ) => {
70+ _route . value = router . currentRoute . value
7571 }
76- } )
72+ nuxtApp . hook ( 'page:finish' , syncCurrentRoute )
73+ router . afterEach ( ( to , from ) => {
74+ // We won't trigger suspense if the component is reused between routes
75+ // so we need to update the route manually
76+ if ( to . matched [ 0 ] ?. components ?. default === from . matched [ 0 ] ?. components ?. default ) {
77+ syncCurrentRoute ( )
78+ }
79+ } )
7780
78- // https://github.com/vuejs/router/blob/main/packages/router/src/router.ts#L1225-L1233
79- const route = { } as { [ K in keyof RouteLocation ] : ComputedRef < RouteLocation [ K ] > }
80- for ( const key in _route . value ) {
81- route [ key as 'path' ] = computed ( ( ) => _route . value [ key as 'path' ] )
82- }
81+ // https://github.com/vuejs/router/blob/main/packages/router/src/router.ts#L1225-L1233
82+ const route = { } as { [ K in keyof RouteLocation ] : ComputedRef < RouteLocation [ K ] > }
83+ for ( const key in _route . value ) {
84+ route [ key as 'path' ] = computed ( ( ) => _route . value [ key as 'path' ] )
85+ }
8386
84- nuxtApp . _route = reactive ( route )
87+ nuxtApp . _route = reactive ( route )
8588
86- nuxtApp . _middleware = nuxtApp . _middleware || {
87- global : [ ] ,
88- named : { } ,
89- }
89+ nuxtApp . _middleware = nuxtApp . _middleware || {
90+ global : [ ] ,
91+ named : { } ,
92+ }
9093
91- const error = useError ( )
94+ const error = useError ( )
9295
93- nuxtApp . hooks . hookOnce ( 'app:mounted' , async ( ) => {
94- const initialLayout = useState < string > ( '_layout' )
95- router . beforeEach ( async ( to , from ) => {
96- to . meta = reactive ( to . meta )
97- if ( nuxtApp . isHydrating && initialLayout . value && ! isReadonly ( to . meta . layout ) ) {
98- to . meta . layout = initialLayout . value as Exclude < PageMeta [ 'layout' ] , Ref | false >
99- }
100- nuxtApp . _processingMiddleware = true
101-
102- type MiddlewareDef = string | RouteMiddleware
103- const middlewareEntries = new Set < MiddlewareDef > ( [
104- ...globalMiddleware ,
105- ...nuxtApp . _middleware . global ,
106- ] )
107- for ( const component of to . matched ) {
108- const componentMiddleware = component . meta . middleware as MiddlewareDef | MiddlewareDef [ ]
109- if ( ! componentMiddleware ) {
110- continue
96+ nuxtApp . hooks . hookOnce ( 'app:mounted' , async ( ) => {
97+ const initialLayout = useState < string > ( '_layout' )
98+ router . beforeEach ( async ( to , from ) => {
99+ to . meta = reactive ( to . meta )
100+ if ( nuxtApp . isHydrating && initialLayout . value && ! isReadonly ( to . meta . layout ) ) {
101+ to . meta . layout = initialLayout . value as Exclude < PageMeta [ 'layout' ] , Ref | false >
111102 }
112- if ( Array . isArray ( componentMiddleware ) ) {
113- for ( const entry of componentMiddleware ) {
114- middlewareEntries . add ( entry )
103+ nuxtApp . _processingMiddleware = true
104+
105+ type MiddlewareDef = string | RouteMiddleware
106+ const middlewareEntries = new Set < MiddlewareDef > ( [
107+ ...globalMiddleware ,
108+ ...nuxtApp . _middleware . global ,
109+ ] )
110+ for ( const component of to . matched ) {
111+ const componentMiddleware = component . meta . middleware as MiddlewareDef | MiddlewareDef [ ]
112+ if ( ! componentMiddleware ) {
113+ continue
114+ }
115+ if ( Array . isArray ( componentMiddleware ) ) {
116+ for ( const entry of componentMiddleware ) {
117+ middlewareEntries . add ( entry )
118+ }
119+ } else {
120+ middlewareEntries . add ( componentMiddleware )
115121 }
116- } else {
117- middlewareEntries . add ( componentMiddleware )
118122 }
119- }
120123
121- for ( const entry of middlewareEntries ) {
122- const middleware =
123- typeof entry === 'string'
124- ? nuxtApp . _middleware . named [ entry ] ||
125- ( await namedMiddleware [ entry ] ?.( ) . then ( ( r : any ) => r . default || r ) )
126- : entry
127-
128- if ( ! middleware ) {
129- if ( process . dev ) {
130- throw new Error (
131- `Unknown route middleware: '${ entry } '. Valid middleware: ${ Object . keys (
132- namedMiddleware
124+ for ( const entry of middlewareEntries ) {
125+ const middleware =
126+ typeof entry === 'string'
127+ ? nuxtApp . _middleware . named [ entry ] ||
128+ ( await namedMiddleware [ entry ] ?.( ) . then ( ( r : any ) => r . default || r ) )
129+ : entry
130+
131+ if ( ! middleware ) {
132+ if ( process . dev ) {
133+ throw new Error (
134+ `Unknown route middleware: '${ entry } '. Valid middleware: ${ Object . keys (
135+ namedMiddleware
136+ )
137+ . map ( mw => `'${ mw } '` )
138+ . join ( ', ' ) } .`
133139 )
134- . map ( mw => `'${ mw } '` )
135- . join ( ', ' ) } .`
136- )
140+ }
141+ throw new Error ( `Unknown route middleware: '${ entry } '.` )
137142 }
138- throw new Error ( `Unknown route middleware: '${ entry } '.` )
139- }
140143
141- const result = await callWithNuxt ( nuxtApp , middleware , [ to , from ] )
142- if ( process . server || ( ! nuxtApp . payload . serverRendered && nuxtApp . isHydrating ) ) {
143- if ( result === false || result instanceof Error ) {
144- const error =
145- result ||
146- createError ( {
147- statusCode : 404 ,
148- statusMessage : `Page Not Found: ${ initialURL } ` ,
149- } )
150- await callWithNuxt ( nuxtApp , showError , [ error ] )
151- return false
144+ const result = await callWithNuxt ( nuxtApp , middleware , [ to , from ] )
145+ if ( process . server || ( ! nuxtApp . payload . serverRendered && nuxtApp . isHydrating ) ) {
146+ if ( result === false || result instanceof Error ) {
147+ const error =
148+ result ||
149+ createError ( {
150+ statusCode : 404 ,
151+ statusMessage : `Page Not Found: ${ initialURL } ` ,
152+ } )
153+ await callWithNuxt ( nuxtApp , showError , [ error ] )
154+ return false
155+ }
156+ }
157+ if ( result || result === false ) {
158+ return result
152159 }
153160 }
154- if ( result || result === false ) {
155- return result
156- }
157- }
158- } )
161+ } )
159162
160- router . afterEach ( async to => {
161- delete nuxtApp . _processingMiddleware
163+ router . afterEach ( async to => {
164+ delete nuxtApp . _processingMiddleware
162165
163- if ( process . client && ! nuxtApp . isHydrating && error . value ) {
164- // Clear any existing errors
165- await callWithNuxt ( nuxtApp , clearError )
166- }
167- if ( to . matched . length === 0 ) {
168- await callWithNuxt ( nuxtApp , showError , [
169- createError ( {
170- statusCode : 404 ,
171- fatal : false ,
172- statusMessage : `Page not found: ${ to . fullPath } ` ,
173- } ) ,
174- ] )
175- } else if ( process . server ) {
176- const currentURL = to . fullPath || '/'
177- if ( ! isEqual ( currentURL , initialURL , { trailingSlash : true } ) ) {
178- const event = await callWithNuxt ( nuxtApp , useRequestEvent )
179- const options = {
180- redirectCode :
181- event . node . res . statusCode !== 200 ? event . node . res . statusCode || 302 : 302 ,
166+ if ( process . client && ! nuxtApp . isHydrating && error . value ) {
167+ // Clear any existing errors
168+ await callWithNuxt ( nuxtApp , clearError )
169+ }
170+ if ( to . matched . length === 0 ) {
171+ await callWithNuxt ( nuxtApp , showError , [
172+ createError ( {
173+ statusCode : 404 ,
174+ fatal : false ,
175+ statusMessage : `Page not found: ${ to . fullPath } ` ,
176+ } ) ,
177+ ] )
178+ } else if ( process . server ) {
179+ const currentURL = to . fullPath || '/'
180+ if ( ! isEqual ( currentURL , initialURL , { trailingSlash : true } ) ) {
181+ const event = await callWithNuxt ( nuxtApp , useRequestEvent )
182+ const options = {
183+ redirectCode :
184+ event . node . res . statusCode !== 200 ? event . node . res . statusCode || 302 : 302 ,
185+ }
186+ await callWithNuxt ( nuxtApp , navigateTo , [ currentURL , options ] )
182187 }
183- await callWithNuxt ( nuxtApp , navigateTo , [ currentURL , options ] )
184188 }
189+ } )
190+
191+ try {
192+ if ( process . client ) {
193+ await router . replace ( {
194+ ...router . resolve ( initialURL ) ,
195+ name : undefined , // #4920, #4982
196+ force : true ,
197+ } )
198+ }
199+ } catch ( error : any ) {
200+ // We'll catch middleware errors or deliberate exceptions here
201+ await nuxtApp . runWithContext ( ( ) => showError ( error ) )
185202 }
186203 } )
187204
188- try {
189- if ( process . client ) {
190- await router . replace ( {
191- ...router . resolve ( initialURL ) ,
192- name : undefined , // #4920, #4982
193- force : true ,
194- } )
195- }
196- } catch ( error : any ) {
197- // We'll catch middleware errors or deliberate exceptions here
198- await nuxtApp . runWithContext ( ( ) => showError ( error ) )
199- }
200- } )
201-
202- return { provide : { router } }
205+ return { provide : { router } }
206+ } ,
203207} ) as Plugin < { router : Router } >
204208
205209// https://github.com/vuejs/router/blob/4a0cc8b9c1e642cdf47cc007fa5bbebde70afc66/packages/router/src/history/html5.ts#L37
0 commit comments