Skip to content
Comvi

@comvi/nuxt composables

View .md

Every composable here is auto-imported once the module is registered. Module options, comvi.i18n.ts and the server utilities are on @comvi/nuxt.

useI18n, useI18nLoader, useI18nPlugins, useLocalePath, useSwitchLocalePath, useLocaleRoute, useLocaleHead, useRouteConfig; types UseI18nReturn, UseI18nLoaderReturn, UseI18nPluginsReturn, LocaleHeadOptions, GetPathnameOptions. Nuxt auto-imports the values, not the types: import a type from the composable’s file, @comvi/nuxt/runtime/composables/useI18n, …/capabilities, …/useLocaleHead or …/useRouteConfig.

Every example assumes the module is registered:

nuxt.config.ts
import { defineNuxtConfig } from 'nuxt/config';
export default defineNuxtConfig({
modules: ['@comvi/nuxt'],
comvi: { defaultLocale: 'en', locales: [{ code: 'en', name: 'English' }] },
});
function useI18n<D extends DefaultTranslationParams = {}>(ns?: string): UseI18nReturn<D>
interface UseI18nReturn<D> extends VueUseI18nReturn<D> {
locales: Ref<readonly string[]>;
defaultLocale: Ref<string>;
}

@comvi/vue’s useI18n() with two Nuxt members, and a setLocale that also advances the Nuxt locale state the middleware watches.

Returned Type Meaning
locales Ref<readonly string[]> Configured locale codes
defaultLocale Ref<string> Configured default locale
t, tRaw, locale, setLocale, isLoading, isInitializing, isInitialized, dir, messagesCache, cacheRevision, defaultParams, loadedLocales, activeNamespaces, defaultNamespace as in @comvi/vue Reactive state
addMessages, setFallbackLocale, setDefaultParams, clearMessages, hasLocale, hasTranslation, on, reportError, destroy, formatNumber, formatDate, formatCurrency, formatRelativeTime as in @comvi/vue Methods

hasTranslationNow() and hasLocaleNow() are on the instance, useNuxtApp().$i18n, not on the composable.

app/components/Greeting.vue
<script setup lang="ts">
const { t, locale, locales, setLocale } = useI18n();
</script>
<template>
<h1>{{ t('page.title') }}</h1>
<select :value="locale" @change="setLocale(($event.target as HTMLSelectElement).value)">
<option v-for="code in locales" :key="code" :value="code">{{ code }}</option>
</select>
</template>
function useI18nLoader(): UseI18nLoaderReturn // AcquiredLoaderApi
function useI18nPlugins(): UseI18nPluginsReturn // AcquiredPluginsApi

@comvi/vue’s capability composables, unchanged. Each throws when the i18n instance has no such capability, and the module’s default instance has none; compose it in comvi.i18n.ts.

app/components/LazyNamespace.vue
<script setup lang="ts">
const { t } = useI18n('dashboard');
const { addActiveNamespace } = useI18nLoader();
onMounted(() => void addActiveNamespace('dashboard'));
</script>
<template>
<h1>{{ t('page.title') }}</h1>
</template>
function useLocalePath(): (path: RouteLocationRaw, locale?: string) => string
Argument Type Default Meaning
path RouteLocationRaw required The path or route object to prefix
locale string current locale Locale for the generated path

An absolute URL, a protocol-relative URL, a mailto: or tel: link, or a query-only or hash-only string is returned unchanged.

app/components/About.vue
<script setup lang="ts">
const localePath = useLocalePath();
</script>
<template>
<NuxtLink :to="localePath('/about')">About</NuxtLink>
</template>
function useSwitchLocalePath(): (locale: string) => string

The current page’s URL in another locale; a locale outside locales falls back to defaultLocale with a development warning. With localeDetection.queryParam set, the parameter is added or updated in every prefix mode; other query parameters and the hash are kept.

app/components/Switcher.vue
<script setup lang="ts">
const switchLocalePath = useSwitchLocalePath();
</script>
<template>
<NuxtLink :to="switchLocalePath('de')">Deutsch</NuxtLink>
</template>
function useLocaleRoute(): (route: RouteLocationRaw, locale?: string) => RouteLocationResolved | undefined

Like useLocalePath(), returning the resolved route object.

function useLocaleHead(options?: LocaleHeadOptions): ComputedRef<Record<string, unknown>>
Option Type Default Meaning
baseUrl string auto-detected Base for canonical and alternate links
addOgLocale boolean true og:locale and og:locale:alternate
addAlternateLinks boolean true hreflang links, with iso codes when configured, plus an x-default link
addCanonical boolean true Canonical <link>
addDir boolean true <html dir>; a locale object’s dir wins, else the direction of the lang tag
addLang boolean true <html lang>
app/app.vue
<script setup lang="ts">
useLocaleHead({ baseUrl: 'https://example.com' });
</script>
<template>
<NuxtPage />
</template>

Call it for the canonical link, the hreflang alternates and og:locale. The module already writes <html lang> and <html dir> through the head option, with the same values addLang and addDir produce, so the two entries agree; with comvi.head: false, addLang and addDir are the way to get them back.

function useRouteConfig(): {
locales: string[];
defaultLocale: string;
localePrefix: 'always' | 'as-needed' | 'never';
getPathname: (options: { locale: string; href: string }) => string;
getAllLocalizedPaths: (href: string) => Array<{ locale: string; path: string }>;
}

App-side only: it reads useRuntimeConfig() from #app, so a Nitro handler under server/ reads useRuntimeConfig(event).public.comvi instead. getAllLocalizedPaths is a closure, not an export.

app/components/Alternates.vue
<script setup lang="ts">
const { getAllLocalizedPaths } = useRouteConfig();
const alternates = getAllLocalizedPaths('/about').map(({ locale, path }) => ({
locale,
href: `https://example.com${path}`,
}));
</script>
<template>
<ul>
<li v-for="a in alternates" :key="a.locale">{{ a.href }}</li>
</ul>
</template>
  • @comvi/nuxt: module options, comvi.i18n.ts, the server utilities and the setup hook.
  • Nuxt: the guide: worked setups for the module and its comvi.i18n.ts.
  • Switch the locale: what the routing composables are for, across frameworks.