diff --git a/specs/fixtures/routing/pages/index.vue b/specs/fixtures/routing/pages/index.vue
index 16547bf01..5ccd636ac 100644
--- a/specs/fixtures/routing/pages/index.vue
+++ b/specs/fixtures/routing/pages/index.vue
@@ -45,6 +45,11 @@ const localeRoute = useLocaleRoute()
{{ localePath('vue-i18n') }}
+
+
+ {{ localePath('https://github.com') }}
+ {{ localePath('mailto:example@mail.com') }}
+ {{ localePath('tel:+31612345678') }}
diff --git a/specs/routing/routing-tests.ts b/specs/routing/routing-tests.ts
index 55d9c5565..bbf701956 100644
--- a/specs/routing/routing-tests.ts
+++ b/specs/routing/routing-tests.ts
@@ -64,6 +64,11 @@ export async function localePathTests(strategy: Strategies) {
// undefined name
expect(await getText(page, '#locale-path .undefined-name')).toEqual('')
+ // external
+ expect(await getText(page, '#locale-path .external-link')).toEqual('https://github.com')
+ expect(await getText(page, '#locale-path .external-mail')).toEqual('mailto:example@mail.com')
+ expect(await getText(page, '#locale-path .external-phone')).toEqual('tel:+31612345678')
+
// for vue-router deprecation
// https://github.com/vuejs/router/blob/main/packages/router/CHANGELOG.md#414-2022-08-22
expect(consoleLogs.find(log => log.text.includes('Discarded invalid param(s)'))).toBeFalsy()
diff --git a/src/runtime/routing/compatibles/routing.ts b/src/runtime/routing/compatibles/routing.ts
index 72c2100cc..965ec0f47 100644
--- a/src/runtime/routing/compatibles/routing.ts
+++ b/src/runtime/routing/compatibles/routing.ts
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { isString, assign } from '@intlify/shared'
-import { parsePath, parseQuery, withTrailingSlash, withoutTrailingSlash } from 'ufo'
+import { hasProtocol, parsePath, parseQuery, withTrailingSlash, withoutTrailingSlash } from 'ufo'
import { nuxtI18nOptions, DEFAULT_DYNAMIC_PARAMS_KEY } from '#build/i18n.options.mjs'
import { unref } from '#imports'
@@ -75,6 +75,11 @@ export function localePath(
route: RouteLocationRaw,
locale?: Locale // TODO: locale should be more type inference (completion)
): string {
+ // return external url as is
+ if (typeof route === 'string' && hasProtocol(route, { acceptRelative: true })) {
+ return route
+ }
+
const localizedRoute = resolveRoute(common, route, locale)
return localizedRoute == null ? '' : localizedRoute.redirectedFrom?.fullPath || localizedRoute.fullPath
}