>
/**
* Where to redirect if the route is directly matched. The redirection happens
* before any navigation guard and triggers a new navigation with the new
diff --git a/packages/nuxt/src/pages/runtime/router.ts b/packages/nuxt/src/pages/runtime/router.ts
index 03bc591227..15dc5bc074 100644
--- a/packages/nuxt/src/pages/runtime/router.ts
+++ b/packages/nuxt/src/pages/runtime/router.ts
@@ -159,7 +159,8 @@ export default defineNuxtPlugin(async (nuxtApp) => {
if (process.server || (!nuxtApp.payload.serverRendered && nuxtApp.isHydrating)) {
if (result === false || result instanceof Error) {
const error = result || createError({
- statusMessage: `Route navigation aborted: ${initialURL}`
+ statusCode: 404,
+ statusMessage: `Page Not Found: ${initialURL}`
})
return callWithNuxt(nuxtApp, showError, [error])
}
diff --git a/packages/nuxt/src/pages/runtime/validate.ts b/packages/nuxt/src/pages/runtime/validate.ts
new file mode 100644
index 0000000000..14d5a8aedd
--- /dev/null
+++ b/packages/nuxt/src/pages/runtime/validate.ts
@@ -0,0 +1,12 @@
+import { createError, defineNuxtRouteMiddleware } from '#app'
+
+export default defineNuxtRouteMiddleware(async (to) => {
+ if (!to.meta?.validate) { return }
+
+ const result = await Promise.resolve(to.meta.validate(to))
+ if (typeof result === 'boolean') {
+ return result
+ }
+
+ return createError(result)
+})
diff --git a/test/basic.test.ts b/test/basic.test.ts
index 9a590cafdb..3a40675be7 100644
--- a/test/basic.test.ts
+++ b/test/basic.test.ts
@@ -65,6 +65,11 @@ describe('pages', () => {
expect(headers.get('location')).toEqual('/')
})
+ it('validates routes', async () => {
+ const { status } = await fetch('/forbidden')
+ expect(status).toEqual(404)
+ })
+
it('render 404', async () => {
const html = await $fetch('/not-found')
diff --git a/test/fixtures/basic/pages/[...slug].vue b/test/fixtures/basic/pages/[...slug].vue
index 47a02c1123..a805ed7aea 100644
--- a/test/fixtures/basic/pages/[...slug].vue
+++ b/test/fixtures/basic/pages/[...slug].vue
@@ -4,3 +4,9 @@
404 at {{ $route.params.slug[0] }}
+
+