diff --git a/docs/content/1.getting-started/7.i18n/1.nuxt.md b/docs/content/1.getting-started/7.i18n/1.nuxt.md
index 4f64b5e3..94b9cb4e 100644
--- a/docs/content/1.getting-started/7.i18n/1.nuxt.md
+++ b/docs/content/1.getting-started/7.i18n/1.nuxt.md
@@ -60,7 +60,7 @@ import { fr } from '@nuxt/ui-pro/locale'
### Custom locale
-You also have the option to add your own locale using `defineLocale`:
+You can create your own locale using the `defineLocale` composable:
::module-only
@@ -125,6 +125,65 @@ Look at the `code` parameter, there you need to pass the iso code of the languag
::
+### Extend locale :badge{label="Soon" class="align-text-top"}
+
+You can customize an existing locale by overriding its `messages` or `code` using the `extendLocale` composable:
+
+::module-only
+
+#ui
+:::div
+
+```vue [app.vue]
+
+
+
+
+
+
+
+```
+
+:::
+
+#ui-pro
+:::div
+
+```vue [app.vue]
+
+
+
+
+
+
+
+```
+
+:::
+::
+
### Dynamic locale
To dynamically switch between languages, you can use the [Nuxt I18n](https://i18n.nuxtjs.org/) module.
diff --git a/docs/content/1.getting-started/7.i18n/2.vue.md b/docs/content/1.getting-started/7.i18n/2.vue.md
index 9476433c..a35e31a7 100644
--- a/docs/content/1.getting-started/7.i18n/2.vue.md
+++ b/docs/content/1.getting-started/7.i18n/2.vue.md
@@ -60,7 +60,7 @@ import { fr } from '@nuxt/ui-pro/locale'
### Custom locale
-You also have the option to add your locale using `defineLocale`:
+You can create your own locale using the `defineLocale` composable:
::module-only
@@ -127,6 +127,67 @@ Look at the `code` parameter, there you need to pass the iso code of the languag
::
+### Extend locale :badge{label="Soon" class="align-text-top"}
+
+You can customize an existing locale by overriding its `messages` or `code` using the `extendLocale` composable:
+
+::module-only
+
+#ui
+:::div
+
+```vue [App.vue]
+
+
+
+
+
+
+
+```
+
+:::
+
+#ui-pro
+:::div
+
+```vue [App.vue]
+
+
+
+
+
+
+
+```
+
+:::
+::
+
### Dynamic locale
To dynamically switch between languages, you can use the [Vue I18n](https://vue-i18n.intlify.dev/) plugin.
diff --git a/src/runtime/composables/defineLocale.ts b/src/runtime/composables/defineLocale.ts
index f5f977f0..89954ed7 100644
--- a/src/runtime/composables/defineLocale.ts
+++ b/src/runtime/composables/defineLocale.ts
@@ -1,5 +1,6 @@
import { defu } from 'defu'
import type { Locale, Direction } from '../types/locale'
+import type { DeepPartial } from '../types/utils'
interface DefineLocaleOptions {
name: string
@@ -12,3 +13,8 @@ interface DefineLocaleOptions {
export function defineLocale(options: DefineLocaleOptions): Locale {
return defu, [{ dir: Direction }]>(options, { dir: 'ltr' })
}
+
+/* @__NO_SIDE_EFFECTS__ */
+export function extendLocale(locale: Locale, options: Partial>>): Locale {
+ return defu, [DefineLocaleOptions]>(options, locale)
+}
diff --git a/src/runtime/types/utils.ts b/src/runtime/types/utils.ts
index 6d2dc68d..48ca5b42 100644
--- a/src/runtime/types/utils.ts
+++ b/src/runtime/types/utils.ts
@@ -1,6 +1,10 @@
import type { VNode } from 'vue'
import type { AcceptableValue as _AcceptableValue } from 'reka-ui'
+export type DeepPartial = {
+ [P in keyof T]?: T[P] extends object ? DeepPartial : T[P] | undefined
+}
+
export type DynamicSlotsKeys = (
Name extends string
? Suffix extends string