What Causes This Error?
This error occurs when you try to navigate to an external URL (a URL on a different domain) using Nuxt’s navigateTo() function without explicitly allowing external navigation.
Nuxt blocks external navigation by default as a security measure to prevent unintended redirects to malicious sites.
The Fix
Add { external: true } to your navigateTo() call:
// ❌ Wrong - will throw an error
navigateTo('https://google.com')
// ✅ Correct - explicitly allow external navigation
navigateTo('https://google.com', { external: true })
Common Scenarios
Redirecting After Authentication
// In your login handler or middleware
const handleLogin = async () => {
await login()
// Redirect to external dashboard
navigateTo('https://dashboard.example.com', { external: true })
}
OAuth Redirects
// Redirecting to OAuth provider
const loginWithGoogle = () => {
navigateTo('https://accounts.google.com/oauth/authorize?...', {
external: true
})
}
Payment Gateway Redirects
// Redirecting to payment processor
const redirectToPayment = (paymentUrl: string) => {
navigateTo(paymentUrl, { external: true })
}
In Middleware
// middleware/redirect.ts
export default defineNuxtRouteMiddleware((to) => {
if (to.path === '/old-external') {
return navigateTo('https://new-site.com', { external: true })
}
})
Alternative: Use Window Location
For simple external redirects, you can also use the native browser API:
// Client-side only
if (process.client) {
window.location.href = 'https://external-site.com'
}
Or with a link:
<template>
<!-- For user-initiated navigation, just use a regular link -->
<a href="https://external-site.com" target="_blank" rel="noopener">
Visit External Site
</a>
</template>
Additional Options
navigateTo() accepts several options for external navigation:
navigateTo('https://example.com', {
external: true,
replace: true, // Replace current history entry
redirectCode: 301, // HTTP redirect code (server-side)
open: { // Open in new window/tab
target: '_blank',
windowFeatures: {
width: 500,
height: 500
}
}
})
Open in New Tab
// Open external URL in new tab
navigateTo('https://example.com', {
external: true,
open: {
target: '_blank'
}
})
Server-Side Redirects
For server-side redirects (in API routes or server middleware):
// server/api/redirect.ts
export default defineEventHandler((event) => {
return sendRedirect(event, 'https://external-site.com', 302)
})
Security Considerations
Nuxt blocks external navigation by default because:
- Prevents open redirects - Attackers can’t trick users into visiting malicious sites
- Explicit intent - Forces developers to consciously allow external redirects
- Audit trail - Easy to search for
external: truein codebase
Best Practices
// ✅ Validate external URLs before redirecting
const safeExternalRedirect = (url: string) => {
const allowedDomains = ['trusted-site.com', 'partner-site.com']
const urlObj = new URL(url)
if (allowedDomains.includes(urlObj.hostname)) {
navigateTo(url, { external: true })
} else {
console.error('Redirect to untrusted domain blocked:', url)
}
}
Quick Reference
| Navigation Type | Method |
|---|---|
| Internal route | navigateTo('/about') |
| External URL | navigateTo('https://...', { external: true }) |
| New tab | navigateTo('https://...', { external: true, open: { target: '_blank' } }) |
| Native redirect | window.location.href = '...' |