Skip to content

Commit

Permalink
feat: update i18n module and adapt config folder and trad files (#203)
Browse files Browse the repository at this point in the history
* feat: update i18n module and adapt config folder and trad files

* chore: add comment

* feat: add detectBrowserLanguage and default files message

* feat: clean i18n detectBrowserLanguage functionnality

* chore: update en trad

* chore: remove default translation files

* feat(i18n): move constants outside of config file

* feat(i18n): use available locales provided by Nuxt i18n

* fix(i18n): detect browser language

* feat: add useRoadizDetectBrowserLanguage

* chore: remove comments

* refactor: remove detect browser lang const

* chore: remove debug data

* refactor: improve useRoadizDetectBrowserLanguage() readability

---------

Co-authored-by: Manuel Odelain <[email protected]>
  • Loading branch information
timothejoubert and manuelodelain authored Jan 10, 2025
1 parent d464605 commit 2a2c9fe
Show file tree
Hide file tree
Showing 13 changed files with 517 additions and 404 deletions.
2 changes: 1 addition & 1 deletion .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ XILOFONE_BASE_URL=https://xilofone.rezo-zero.com
XILOFONE_USERNAME=
XILOFONE_PASSWORD=
XILOFONE_FILE_ID=
XILOFONE_OUTPUT=assets/locales/
XILOFONE_OUTPUT=i18n/locales/

# SENTRY
#NUXT_PUBLIC_SENTRY_DSN=
1 change: 0 additions & 1 deletion assets/locales/nuxt.fr.json

This file was deleted.

27 changes: 27 additions & 0 deletions components/atoms/VTime/ENLocale.stories.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<script lang="ts" setup>
const { locale } = useI18n()
locale.value = 'en'
</script>

<template>
<NuxtStory>
<NuxtStoryVariant title="Single">
<VTime datetime="2023-06-28T22:00:00+02:00" />
</NuxtStoryVariant>
<NuxtStoryVariant title="Single (with minutes)">
<VTime datetime="2023-06-28T22:15:00+02:00" />
</NuxtStoryVariant>
<NuxtStoryVariant title="Range (multi times / same day)">
<VTime :datetime="['2023-06-28T19:30:00+02:00', '2023-06-28T22:30:00+02:00']" />
</NuxtStoryVariant>
<NuxtStoryVariant title="Range (multi days / same month)">
<VTime :datetime="['2023-06-28T22:30:00+02:00', '2023-06-29T22:30:00+02:00']" />
</NuxtStoryVariant>
<NuxtStoryVariant title="Range (multi days / multi months)">
<VTime :datetime="['2023-06-28T22:30:00+02:00', '2023-07-12T22:30:00+02:00']" />
</NuxtStoryVariant>
<NuxtStoryVariant title="Range (multi years)">
<VTime :datetime="['2023-06-28T22:30:00+02:00', '2024-07-12T22:30:00+02:00']" />
</NuxtStoryVariant>
</NuxtStory>
</template>
19 changes: 19 additions & 0 deletions composables/use-i18n-cookie.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { localeCodes, nuxtI18nOptions } from '#build/i18n.options.mjs'

// Workaround for useCookieLocale() returning empty string
// @see https://github.com/nuxt-modules/i18n/issues/2975
export function useI18nCookie(): Ref<string> {
const locale: Ref<string> = ref('')
const detect = nuxtI18nOptions.detectBrowserLanguage

if (detect && detect.useCookie) {
const cookieKey = detect.cookieKey
const code = useCookie<string>(cookieKey).value ?? null

if (code && localeCodes.includes(code)) {
locale.value = code
}
}

return locale
}
26 changes: 26 additions & 0 deletions composables/use-roadiz-detect-browser-language.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { RoadizAlternateLink } from '@roadiz/types'
import { nuxtI18nOptions } from '#build/i18n.options.mjs'

export async function useRoadizDetectBrowserLanguage({ locale, alternateLinks }: { locale: string, alternateLinks: RoadizAlternateLink[] }) {
const { detectBrowserLanguage } = nuxtI18nOptions

if (!detectBrowserLanguage) return

const isRootPath = useRoute().path === '/' || alternateLinks.some(link => link.url === '/')

if (!isRootPath && detectBrowserLanguage.redirectOn === 'root') return

const cookieLocale = useI18nCookie().value

if (cookieLocale && detectBrowserLanguage.alwaysRedirect !== true) return

const { $i18n } = useNuxtApp()
const browserLocale = useBrowserLocale()
const preferredLocale = detectBrowserLanguage.useCookie ? (cookieLocale || browserLocale) : browserLocale

if (preferredLocale && preferredLocale !== locale && $i18n.locales.value.find(availableLocale => availableLocale.code === preferredLocale)) {
const alternateLink = alternateLinks.find(link => link.locale === preferredLocale)

if (alternateLink) await navigateTo(alternateLink.url, { replace: true, external: true })
}
}
3 changes: 3 additions & 0 deletions constants/i18n.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const I18N_LOCALES = ['fr'] as const
export const I18N_DEFAULT_LOCALE = 'fr'
export const I18N_DEFAULT_TIMEZONE = 'Europe/Paris'
15 changes: 6 additions & 9 deletions i18n.config.ts → i18n/i18n.config.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import type { I18nOptions } from 'vue-i18n'
import type { DateTimeFormat } from '@intlify/core-base'
import { I18N_DEFAULT_TIMEZONE, I18N_LOCALES } from '~/constants/i18n'

export const I18N_LOCALES = ['fr']
export const I18N_DEFAULT_LOCALE = 'fr'
export const I18N_DEFAULT_TIMEZONE = 'Europe/Paris'

// defineI18nConfig() does not work, therefore we need to type the config object
export default {
export default defineI18nConfig(() => ({
datetimeFormats: I18N_LOCALES.reduce(
(acc, cur) => ({
...acc,
Expand Down Expand Up @@ -71,6 +67,7 @@ export default {
},
},
}),
{},
{} as Record<typeof I18N_LOCALES[number], DateTimeFormat>,
),
} satisfies I18nOptions
}),
)
File renamed without changes.
2 changes: 2 additions & 0 deletions i18n/locales/nuxt.fr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
30 changes: 15 additions & 15 deletions layouts/default.vue
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
<script setup lang="ts">
<script lang="ts" setup>
import type { RoadizNodesSources } from '@roadiz/types'
import VFooter from '~/components/organisms/VFooter/VFooter.vue'
// init Roadiz page data (i.e. dynamic page)
await callOnce(async () => {
const route = useRoute()
// check if it's a dynamic page
// if the route is not a dynamic page, return
if (route.name !== 'slug') return
const { webResponse, alternateLinks } = await useRoadizWebResponse()
// fill page data
// init page data for components outside page
useCurrentPage({ webResponse, alternateLinks })
useAlternateLinks(alternateLinks)
// init I18N
const nuxtApp = useNuxtApp()
const locale = (webResponse?.item as RoadizNodesSources)?.translation?.locale
// i18n
const webResponseLocale = (webResponse?.item as RoadizNodesSources)?.translation?.locale
if (locale) {
// set the current global locale
await nuxtApp.$i18n.setLocale(locale)
}
else {
// get the locale from the route (prefix) or cookie ?
}
if (webResponseLocale) {
const { $i18n } = useNuxtApp()
// init alternate links
useAlternateLinks(alternateLinks)
// trying to redirect to the preferred locale
await useRoadizDetectBrowserLanguage({ locale: webResponseLocale, alternateLinks })
if (webResponseLocale !== $i18n.locale.value && $i18n.locales.value.find(availableLocale => availableLocale.code === webResponseLocale)) {
await $i18n.setLocale(webResponseLocale)
}
}
})
</script>

Expand Down
14 changes: 6 additions & 8 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import svgLoader from 'vite-svg-loader'
import type { NuxtPlugin } from '@nuxt/schema'
import { version } from './package.json'
import { I18N_DEFAULT_LOCALE, I18N_LOCALES } from './i18n.config'
import { I18N_DEFAULT_LOCALE, I18N_LOCALES } from './constants/i18n'

const isDev = process.env.NODE_ENV === 'development'

const isGenerate = process.argv.includes('generate')
const isGenerateMaintenance = isGenerate && process.argv.includes('--maintenance')

const isNuxtStories = process.env.NUXT_STORIES === '1'
const plugins: (NuxtPlugin | string)[] = []

Expand Down Expand Up @@ -172,20 +170,20 @@ export default defineNuxtConfig({
},
},
},
// https://v8.i18n.nuxtjs.org/getting-started/setup
// https://i18n.nuxtjs.org/docs/getting-started/usage
i18n: {
strategy: 'prefix_except_default',
detectBrowserLanguage: false,
detectBrowserLanguage: {
useCookie: true,
},
defaultLocale: I18N_DEFAULT_LOCALE,
locales: I18N_LOCALES.map(locale => ({
code: locale,
file: `nuxt.${locale}.json`,
})),
lazy: true,
langDir: 'assets/locales/',
compilation: {
// Message can contains HTML tag
strictMessage: false,
strictMessage: false, // Message can contains HTML tag
},
},
// https://image.nuxt.com/get-started/configuration
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"@nuxt/devtools": "latest",
"@nuxt/eslint": "^0.7.4",
"@nuxt/image": "^1.8.1",
"@nuxtjs/i18n": "^8.5.5",
"@nuxtjs/i18n": "^9.1.1",
"@nuxtjs/robots": "^5.1.0",
"@nuxtjs/sitemap": "^7.0.1",
"@nuxtjs/svg-sprite": "^1.0.2",
Expand Down
Loading

0 comments on commit 2a2c9fe

Please sign in to comment.