Skip to content

Commit

Permalink
feat: add useSetI18nParams composable
Browse files Browse the repository at this point in the history
  • Loading branch information
BobbieGoede committed Nov 29, 2023
1 parent 0e26b0e commit 6752118
Show file tree
Hide file tree
Showing 5 changed files with 288 additions and 22 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
"@types/debug": "^4.1.9",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"@unhead/vue": "^1.8.8",
"bumpp": "^9.2.0",
"changelogithub": "^0.13.0",
"consola": "^3",
Expand All @@ -124,6 +125,7 @@
"typescript": "^5.2.2",
"unbuild": "^2.0.0",
"undici": "^5.27.2",
"unhead": "^1.8.8",
"vitest": "^0.34.6",
"vue": "^3.3.4",
"vue-router": "^4.2.5"
Expand Down
52 changes: 41 additions & 11 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

72 changes: 69 additions & 3 deletions src/runtime/composables.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { useRoute, useRouter, useRequestHeaders, useCookie, useNuxtApp } from '#imports'
import { useRoute, useRouter, useRequestHeaders, useCookie, useNuxtApp, useState } from '#imports'
import { ref } from 'vue'
import { parseAcceptLanguage } from './internal'
import { nuxtI18nInternalOptions, nuxtI18nOptionsDefault, localeCodes as _localeCodes } from '#build/i18n.options.mjs'
import { getActiveHead } from 'unhead'
import {
getComposer,
findBrowserLocale,
getLocale,
getLocales,
useRouteBaseName as _useRouteBaseName,
useLocalePath as _useLocalePath,
useLocaleRoute as _useLocaleRoute,
Expand All @@ -16,8 +19,71 @@ import type { Ref } from 'vue'
import type { DetectBrowserLanguageOptions } from '#build/i18n.options.mjs'

export * from 'vue-i18n'
export type { LocaleObject } from 'vue-i18n-routing'
import type { Locale, LocaleMessages, DefineLocaleMessage, I18nOptions } from 'vue-i18n'
import { type Locale, type LocaleMessages, type DefineLocaleMessage, type I18nOptions, useI18n } from 'vue-i18n'
import type { LocaleObject } from 'vue-i18n-routing'
import {
addAlternateOgLocales,
addCanonicalLinksAndOgUrl,
addCurrentOgLocale,
addHreflangLinks,
getNormalizedLocales,
type HeadParam
} from './utils'

/**
* Returns a function to set i18n params.
*
* @param options - An options, see about details {@link I18nHeadOptions}.
*
* @returns setI18nParams {@link I18nHeadMetaInfo | head properties}.
*
* @public
*/
export function useSetI18nParams(
options?: Pick<
NonNullable<Parameters<typeof _useLocaleHead>[0]>,
'addDirAttribute' | 'addSeoAttributes' | 'identifierAttribute' | 'route' | 'router' | 'i18n'
>
) {
const i18n = useI18n()
const head = getActiveHead()
const locale = getLocale(i18n)
const locales = getNormalizedLocales(getLocales(i18n))
const metaState = useState<Record<string, unknown>>('nuxt-i18n-meta')
const addDirAttribute = options?.addDirAttribute ?? true
const addSeoAttributes = options?.addSeoAttributes ?? true
const idAttribute = options?.identifierAttribute ?? 'id'

const currentLocale = getNormalizedLocales(locales).find(l => l.code === locale) || { code: locale }
const currentLocaleIso = currentLocale.iso
const currentLocaleDir = currentLocale.dir || i18n.defaultDirection

const setMeta = () => {
const metaObject: HeadParam = {
htmlAttrs: {
dir: addDirAttribute ? currentLocaleDir : undefined,
lang: addSeoAttributes && locale && i18n.locales ? currentLocaleIso : undefined
},
link: [],
meta: []
}

// Adding SEO Meta
if (addSeoAttributes && locale && i18n.locales) {
addHreflangLinks(locales as LocaleObject[], metaObject, idAttribute)
addCanonicalLinksAndOgUrl(metaObject, idAttribute, addSeoAttributes)
addCurrentOgLocale(currentLocale, currentLocaleIso, metaObject, idAttribute)
addAlternateOgLocales(locales as LocaleObject[], currentLocaleIso, metaObject, idAttribute)
}

head?.push(metaObject)
}

return function (params: Record<string, unknown>) {
metaState.value = { ...params }
setMeta()
}
}

/**
* The `useRouteBaseName` composable returns a function that gets the route's base name.
Expand Down
14 changes: 11 additions & 3 deletions src/runtime/plugins/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { computed } from 'vue'
import { computed, ref } from 'vue'
import { createI18n } from 'vue-i18n'
import { deepCopy } from '@intlify/shared'
import {
Expand All @@ -14,7 +14,14 @@ import {
getLocale,
getComposer
} from 'vue-i18n-routing'
import { defineNuxtPlugin, useRouter, useRoute, addRouteMiddleware, defineNuxtRouteMiddleware } from '#imports'
import {
defineNuxtPlugin,
useRouter,
useRoute,
addRouteMiddleware,
defineNuxtRouteMiddleware,
useState
} from '#imports'
import {
localeCodes,
vueI18nConfigs,
Expand Down Expand Up @@ -107,7 +114,8 @@ export default defineNuxtPlugin({
...nuxtI18nOptions,
dynamicRouteParamsKey: 'nuxtI18n',
switchLocalePathIntercepter: extendSwitchLocalePathIntercepter(differentDomains, normalizedLocales, nuxtContext),
prefixable: extendPrefixable(differentDomains)
prefixable: extendPrefixable(differentDomains),
dynamicParamsInterceptor: () => useState('nuxt-i18n-meta', () => ref({}))
})

const getDefaultLocale = (defaultLocale: string) => defaultLocale || vueI18nOptions.locale || 'en-US'
Expand Down
Loading

0 comments on commit 6752118

Please sign in to comment.