import type { Router, RouteLocationNormalizedLoaded, NavigationGuard, RouteLocationNormalized, RouteLocationRaw } from 'vue-router' import { sendRedirect } from 'h3' import { useNuxtApp } from '#app' export const useRouter = () => { return useNuxtApp()?.$router as Router } export const useRoute = () => { return useNuxtApp()._route as RouteLocationNormalizedLoaded } export interface RouteMiddleware { (to: RouteLocationNormalized, from: RouteLocationNormalized): ReturnType } 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 } export interface NavigateToOptions { replace?: boolean } export const navigateTo = (to: RouteLocationRaw, options: NavigateToOptions = {}) => { if (isProcessingMiddleware()) { return to } const router = useRouter() if (process.server && useNuxtApp().ssrContext) { // Server-side redirection using h3 res from ssrContext const res = useNuxtApp().ssrContext?.res const redirectLocation = router.resolve(to).fullPath return sendRedirect(res, redirectLocation) } // Client-side redirection using vue-router return options.replace ? router.replace(to) : router.push(to) } /** 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 }