Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions src/parts/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,20 @@ export const setupRouter = () => {
nuxt.options.vite.optimizeDeps.include = nuxt.options.vite.optimizeDeps.include || []
nuxt.options.vite.optimizeDeps.include.push('@ionic/vue-router')

const ROUTER_PLUGIN_RE = /nuxt3?\/dist\/(app\/plugins|pages\/runtime)\/(plugins\/)?router/
const ionicRouterPlugin = {
src: resolve(runtimeDir, 'router'),
mode: 'all',
} as const

nuxt.hook('modules:done', () => {
nuxt.hook('app:resolve', app => {
app.plugins = app.plugins.filter(
p => !p.src.match(/nuxt3?\/dist\/(app\/plugins|pages\/runtime)\/(plugins\/)?router/)
)
app.plugins.unshift({
src: resolve(runtimeDir, 'router'),
mode: 'all',
})
const routerPlugin = app.plugins.findIndex(p => ROUTER_PLUGIN_RE.test(p.src))
if (routerPlugin !== -1) {
app.plugins.splice(routerPlugin, 1, ionicRouterPlugin)
} else {
app.plugins.unshift(ionicRouterPlugin)
}
})
})

Expand Down
57 changes: 32 additions & 25 deletions src/runtime/router.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import { createRouter, createWebHistory, createMemoryHistory } from '@ionic/vue-router'

import { computed, ComputedRef, reactive, shallowRef } from 'vue'
import { createWebHashHistory, NavigationGuard, RouteLocation } from 'vue-router'
import {
createRouter,
createWebHistory,
createWebHashHistory,
createMemoryHistory,
} from '@ionic/vue-router'

import { computed, isReadonly, reactive, shallowRef } from 'vue'
import type { ComputedRef, Ref } from 'vue'
import type { RouteLocation, Router } from 'vue-router'
import { createError } from 'h3'
import { withoutBase, isEqual } from 'ufo'
import {
callWithNuxt,
defineNuxtPlugin,
useRuntimeConfig,
showError,
clearError,
navigateTo,
useError,
useState,
} from '#app'

import type { PageMeta, RouteMiddleware, Plugin } from '#app'
import { callWithNuxt, defineNuxtPlugin, useRuntimeConfig } from '#app/nuxt'
import { showError, clearError, useError } from '#app/composables/error'
import { useRequestEvent } from '#app/composables/ssr'
import { useState } from '#app/composables/state'
import { navigateTo } from '#app/composables/router'

// @ts-expect-error virtual module
import { globalMiddleware, namedMiddleware } from '#build/middleware'
Expand Down Expand Up @@ -89,12 +92,12 @@ export default defineNuxtPlugin(async nuxtApp => {
const initialLayout = useState<string>('_layout')
router.beforeEach(async (to, from) => {
to.meta = reactive(to.meta)
if (nuxtApp.isHydrating) {
to.meta.layout = initialLayout.value ?? to.meta.layout
if (nuxtApp.isHydrating && initialLayout.value && !isReadonly(to.meta.layout)) {
to.meta.layout = initialLayout.value as Exclude<PageMeta['layout'], Ref | false>
}
nuxtApp._processingMiddleware = true

type MiddlewareDef = string | NavigationGuard
type MiddlewareDef = string | RouteMiddleware
const middlewareEntries = new Set<MiddlewareDef>([
...globalMiddleware,
...nuxtApp._middleware.global,
Expand Down Expand Up @@ -137,9 +140,11 @@ export default defineNuxtPlugin(async nuxtApp => {
const error =
result ||
createError({
statusMessage: `Route navigation aborted: ${initialURL}`,
statusCode: 404,
statusMessage: `Page Not Found: ${initialURL}`,
})
return callWithNuxt(nuxtApp, showError, [error])
await callWithNuxt(nuxtApp, showError, [error])
return false
}
}
if (result || result === false) {
Expand All @@ -156,25 +161,27 @@ export default defineNuxtPlugin(async nuxtApp => {
await callWithNuxt(nuxtApp, clearError)
}
if (to.matched.length === 0) {
callWithNuxt(nuxtApp, showError, [
await callWithNuxt(nuxtApp, showError, [
createError({
statusCode: 404,
fatal: false,
statusMessage: `Page not found: ${to.fullPath}`,
}),
])
} else if (process.server && to.matched[0].name === '404' && nuxtApp.ssrContext) {
nuxtApp.ssrContext.event.res.statusCode = 404
} else if (process.server) {
const currentURL = to.fullPath || '/'
if (!isEqual(currentURL, initialURL)) {
await callWithNuxt(nuxtApp, navigateTo, [currentURL])
if (!isEqual(currentURL, initialURL, { trailingSlash: true })) {
const event = await callWithNuxt(nuxtApp, useRequestEvent)
const options = {
redirectCode: event.node.res.statusCode !== 200 ? event.node.res.statusCode || 302 : 302,
}
await callWithNuxt(nuxtApp, navigateTo, [currentURL, options])
}
}
})

return { provide: { router } }
})
}) as Plugin<{ router: Router }>

// https://github.com/vuejs/router/blob/4a0cc8b9c1e642cdf47cc007fa5bbebde70afc66/packages/router/src/history/html5.ts#L37
function createCurrentLocation(base: string, location: Location): string {
Expand Down