2022-03-16 22:44:22 +00:00
|
|
|
import type { Router, RouteLocationNormalizedLoaded, NavigationGuard, RouteLocationNormalized, RouteLocationRaw, NavigationFailure } from 'vue-router'
|
2022-03-16 21:39:47 +00:00
|
|
|
import { sendRedirect } from 'h3'
|
2022-02-21 13:03:42 +00:00
|
|
|
import { useNuxtApp } from '#app'
|
|
|
|
|
|
|
|
export const useRouter = () => {
|
|
|
|
return useNuxtApp()?.$router as Router
|
|
|
|
}
|
|
|
|
|
|
|
|
export const useRoute = () => {
|
|
|
|
return useNuxtApp()._route as RouteLocationNormalizedLoaded
|
|
|
|
}
|
|
|
|
|
2022-04-06 12:45:18 +00:00
|
|
|
export const useActiveRoute = () => {
|
|
|
|
return useNuxtApp()._activeRoute as RouteLocationNormalizedLoaded
|
|
|
|
}
|
|
|
|
|
2022-02-21 13:03:42 +00:00
|
|
|
export interface RouteMiddleware {
|
|
|
|
(to: RouteLocationNormalized, from: RouteLocationNormalized): ReturnType<NavigationGuard>
|
|
|
|
}
|
|
|
|
|
|
|
|
export const defineNuxtRouteMiddleware = (middleware: RouteMiddleware) => middleware
|
|
|
|
|
|
|
|
export interface AddRouteMiddlewareOptions {
|
|
|
|
global?: boolean
|
|
|
|
}
|
|
|
|
|
|
|
|
interface AddRouteMiddleware {
|
|
|
|
(name: string, middleware: RouteMiddleware, options?: AddRouteMiddlewareOptions): void
|
|
|
|
(middleware: RouteMiddleware): void
|
|
|
|
}
|
|
|
|
|
|
|
|
export const addRouteMiddleware: AddRouteMiddleware = (name: string | RouteMiddleware, middleware?: RouteMiddleware, options: AddRouteMiddlewareOptions = {}) => {
|
|
|
|
const nuxtApp = useNuxtApp()
|
|
|
|
if (options.global || typeof name === 'function') {
|
|
|
|
nuxtApp._middleware.global.push(typeof name === 'function' ? name : middleware)
|
|
|
|
} else {
|
|
|
|
nuxtApp._middleware.named[name] = middleware
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const isProcessingMiddleware = () => {
|
|
|
|
try {
|
|
|
|
if (useNuxtApp()._processingMiddleware) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
} catch {
|
|
|
|
// Within an async middleware
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2022-03-16 21:39:47 +00:00
|
|
|
export interface NavigateToOptions {
|
|
|
|
replace?: boolean
|
2022-04-19 19:13:11 +00:00
|
|
|
redirectCode?: number
|
2022-03-16 21:39:47 +00:00
|
|
|
}
|
|
|
|
|
2022-03-16 22:44:22 +00:00
|
|
|
export const navigateTo = (to: RouteLocationRaw, options: NavigateToOptions = {}): Promise<void | NavigationFailure> | RouteLocationRaw => {
|
2022-02-21 13:03:42 +00:00
|
|
|
if (isProcessingMiddleware()) {
|
|
|
|
return to
|
|
|
|
}
|
2022-03-16 21:39:47 +00:00
|
|
|
const router = useRouter()
|
2022-04-19 19:13:11 +00:00
|
|
|
if (process.server) {
|
|
|
|
const nuxtApp = useNuxtApp()
|
|
|
|
if (nuxtApp.ssrContext && nuxtApp.ssrContext.event) {
|
2022-04-07 11:28:04 +00:00
|
|
|
const redirectLocation = router.resolve(to).fullPath
|
2022-04-19 19:13:11 +00:00
|
|
|
return nuxtApp.callHook('app:redirected').then(() => sendRedirect(nuxtApp.ssrContext.event, redirectLocation, options.redirectCode || 301))
|
2022-04-07 11:28:04 +00:00
|
|
|
}
|
2022-03-16 21:39:47 +00:00
|
|
|
}
|
|
|
|
// Client-side redirection using vue-router
|
|
|
|
return options.replace ? router.replace(to) : router.push(to)
|
2022-02-21 13:03:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/** This will abort navigation within a Nuxt route middleware handler. */
|
|
|
|
export const abortNavigation = (err?: Error | string) => {
|
|
|
|
if (process.dev && !isProcessingMiddleware()) {
|
|
|
|
throw new Error('abortNavigation() is only usable inside a route middleware handler.')
|
|
|
|
}
|
|
|
|
if (err) {
|
|
|
|
throw err instanceof Error ? err : new Error(err)
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|