config language detection and translation

This commit is contained in:
Rivaland Tawouafo 2024-01-28 07:46:55 +01:00
parent 34e27e287e
commit 3d671abbb7
10 changed files with 56 additions and 78 deletions

View file

@ -2,14 +2,10 @@
const { locale } = useI18n({ useScope: 'global' })
const currentLang = computed(()=>{
return locale.value === 'de-DE' ? 'de' : 'en'
return locale.value === 'de' ? 'de' : 'en'
})
const {
cookiesEnabled,
cookiesEnabledIds,
isConsentGiven,
isModalActive,
moduleOptions,
} = useCookieControl()
watch(
() => cookiesEnabledIds.value,
@ -18,8 +14,7 @@ watch(
!previous?.includes('google-analytics') &&
current?.includes('google-analytics')
) {
// cookie with id `google-analytics` got added
window.location.reload() // placeholder for your custom change handler
window.location.reload()
}
},
{ deep: true },

View file

@ -1,40 +1,45 @@
<script setup lang="ts">
const { t } = useI18n({ useScope: 'global' })
const localePath = useLocalePath()
</script>
<template>
<header class="w-full absolute top-0 left-0 h-28 text-white flex justify-center items-center px-4">
<div class="container max-w-[1200px] flex justify-between items-center">
<!-- LOGO -->
<NuxtLink to="/"><img src="~/assets/img/logo_conop_systems.png" alt="conop-systems logo"
<NuxtLink :to="localePath('/')"><img src="~/assets/img/logo_conop_systems.png" alt="conop-systems logo"
class="w-16 md:w-32 object-cover">
</NuxtLink>
<!-- NAVIGATION -->
<nav class="hidden md:block">
<ul class="gap-4 text-base lg:text-lg flex">
<li>
<NuxtLink active-class="link__active" class="hover:text-c-blue hover:underline" to="/">
<NuxtLink active-class="link__active" class="hover:text-c-blue hover:underline"
:to="localePath('/')">
{{ t('header.home') }}
</NuxtLink>
</li>
<li>
<NuxtLink exact-active-class="text-c-blue" class="hover:text-c-blue hover:underline" to="/services">
<NuxtLink exact-active-class="text-c-blue" class="hover:text-c-blue hover:underline"
:to="localePath('/services')">
{{ t('header.services') }}
</NuxtLink>
</li>
<li>
<NuxtLink exact-active-class="text-c-blue" class="hover:text-c-blue hover:underline"
to="/portfolio">
:to="localePath('/portfolio')">
{{ t('header.portfolio') }}
</NuxtLink>
</li>
<li>
<NuxtLink exact-active-class="text-c-blue" class="hover:text-c-blue hover:underline" to="/about">
<NuxtLink exact-active-class="text-c-blue" class="hover:text-c-blue hover:underline"
:to="localePath('/about')">
{{ t('header.about') }}
</NuxtLink>
</li>
<li>
<NuxtLink exact-active-class="text-c-blue" class="hover:text-c-blue hover:underline" to="/blog">
<NuxtLink exact-active-class="text-c-blue" class="hover:text-c-blue hover:underline"
:to="localePath('/blog')">
{{ t('header.blog') }}
</NuxtLink>
</li>
@ -44,7 +49,7 @@ const { t } = useI18n({ useScope: 'global' })
<div class=" justify-between items-center gap-2 md:flex">
<LangDropdown class="hidden md:inline-block"></LangDropdown>
<button class="hidden lg:inline-block btn__talk px-4 py-2 uppercase text-base rounded-full">
Let's Talk
{{ t('header.letstalk') }}
<Icon name="material-symbols-light:arrow-right-alt-rounded" class="btn__talk__icon" size="40" />
</button>
</div>
@ -80,5 +85,4 @@ const { t } = useI18n({ useScope: 'global' })
&:hover .btn__talk__icon {
color: $conop-dark-blue;
}
}
</style>
}</style>

View file

@ -4,21 +4,20 @@ import { ref } from 'vue'
import germanyFlag from '~/assets/img/germany_flag.png'
import usaFlag from '~/assets/img/usa_flag.png'
const { t, locale } = useI18n({ useScope: 'global' })
const { locale, setLocale } = useI18n({ useScope: 'global' })
const switchLocalePath = useSwitchLocalePath()
const hiddenLang = ref(true)
const currentLang = computed(() => {
return locale.value === 'de-DE' ? 'De' : 'En'
})
const currentLangFlag = computed(() => {
return locale.value === 'de-DE' ? germanyFlag : usaFlag
return locale.value === 'de' ? germanyFlag : usaFlag
})
const dropdown = ref<HTMLDivElement>()
const showlangDrop = () => {
hiddenLang.value = !hiddenLang.value
}
const changeLang = (lang: Lang) => {
locale.value = lang
setLocale(lang)
localStorage.setItem('lang', lang)
hiddenLang.value = true
@ -31,11 +30,14 @@ const closeDropdown = (event: any) => {
};
onMounted(() => {
window.addEventListener('click', closeDropdown);
const lang = localStorage.getItem('lang')
if (lang) {
locale.value = lang
setLocale(lang)
}
window.addEventListener('click', closeDropdown);
});
onUnmounted(() => {
@ -47,8 +49,8 @@ onUnmounted(() => {
<div class="dropdown relative" ref="dropdown">
<button class="dropdown__btn flex justify-between items-center gap-1" @click="showlangDrop">
<!-- <Icon name="mdi:web" size="30" color="white" /> -->
<img :src="currentLangFlag" class="w-10 transition-all" :alt="`${currentLang} flag`">
<span class="uppercase text-lg">{{ currentLang }}</span>
<img :src="currentLangFlag" class="w-10 transition-all" :alt="`${locale} flag`">
<span class="uppercase text-lg">{{ locale }}</span>
<Icon name="material-symbols-light:keyboard-arrow-up-rounded" :class="hiddenLang ? 'rotate-180' : ''"
class="cursor-pointer transition-all" size="40" color="white" />
</button>
@ -58,11 +60,11 @@ onUnmounted(() => {
<li>
<span class="block px-4 py-2 hover:bg-gray-600 hover:text-white transition-all"
@click="changeLang('de-DE')">Deutsch</span>
@click="changeLang('de')">Deutsch</span>
</li>
<li>
<span class="block px-4 py-2 hover:bg-gray-600 hover:text-white transition-all"
@click="changeLang('en-US')">English</span>
@click="changeLang('en')">English</span>
</li>
</ul>
</div>
@ -71,5 +73,4 @@ onUnmounted(() => {
<style scoped></style>
~/locales/messages
<style scoped></style>

View file

@ -2,15 +2,6 @@ import { messages } from '~/locales/messages'
export default defineI18nConfig(() => ({
legacy: false,
locales: ['en-US', 'de-DE'],
defaultLocale: 'de-DE',
fallbackLocale: 'en',
messages: messages,
detectBrowserLanguage: {
useCookie: true,
cookieKey: 'i18n_redirected',
redirectOn: 'root',
alwaysRedirect: true
}
}))

View file

@ -2,8 +2,8 @@ import enUS from './en-US.json'
import deDE from './de-DE.json'
export const messages = {
"en-US": enUS,
"de-DE": deDE,
"en": enUS,
"de": deDE,
};
export type Lang = 'en-US' | 'de-DE'
export type Lang = 'en' | 'de'

View file

@ -2,7 +2,12 @@
export default defineNuxtConfig({
devtools: { enabled: true },
css: ["~/assets/css/main.scss"],
modules: ["nuxt-icon", "@nuxtjs/i18n", "nuxt-aos", '@dargmuesli/nuxt-cookie-control'],
modules: [
"nuxt-icon",
"@nuxtjs/i18n",
"nuxt-aos",
"@dargmuesli/nuxt-cookie-control",
],
postcss: {
plugins: {
tailwindcss: {},
@ -19,17 +24,28 @@ export default defineNuxtConfig({
},
},
i18n: {
locales: [
{ code: "en", iso: "en-US", name: "English" },
{ code: "de", iso: "de-DE", name: "Deutsch" },
],
strategy: 'prefix',
defaultLocale: "en",
vueI18n: "./i18n.config.ts",
detectBrowserLanguage: {
useCookie: true,
cookieKey: "i18n_redirected",
redirectOn: "root",
alwaysRedirect: true,
},
},
aos: {
startEvent: "DOMContentLoaded",
},
cookieControl: {
locales: ['en', 'de'],
locales: ["en", "de"],
colors: {
barBackground: "#00304A",
barButtonBackground: "#0AA5D3"
}
}
barButtonBackground: "#0AA5D3",
},
},
});

28
package-lock.json generated
View file

@ -15,7 +15,6 @@
"autoprefixer": "^10.4.17",
"nuxt": "^3.8.2",
"nuxt-aos": "^1.2.2",
"nuxt-delay-hydration": "^1.3.3",
"nuxt-icon": "^0.6.8",
"postcss": "^8.4.33",
"sass": "^1.70.0",
@ -6918,12 +6917,6 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
"dev": true
},
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@ -8697,18 +8690,6 @@
"defu": "^6.1.4"
}
},
"node_modules/nuxt-delay-hydration": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/nuxt-delay-hydration/-/nuxt-delay-hydration-1.3.3.tgz",
"integrity": "sha512-M0PR0s8M7ugUpq7hQbMZ4A5DpkIGoCeeXM5mSJyHHi4yx7M5zep2zNweA/M1rMN+RIE3O/PlxuWYzZK73GiVMA==",
"dev": true,
"dependencies": {
"@nuxt/kit": "^3.8.1",
"lodash-es": "^4.17.21",
"packrup": "^0.1.0",
"radix3": "^1.1.0"
}
},
"node_modules/nuxt-icon": {
"version": "0.6.8",
"resolved": "https://registry.npmjs.org/nuxt-icon/-/nuxt-icon-0.6.8.tgz",
@ -8937,15 +8918,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/packrup": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/packrup/-/packrup-0.1.0.tgz",
"integrity": "sha512-HnUl9ztHGty5ZK13WM8Q7854SWPKH/eCT+MiTO0P1qCu1Y4S5PPJ8E9MwD3cnjSr7PUPzXDnmOVJIKM043OfJQ==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/harlan-zw"
}
},
"node_modules/pacote": {
"version": "17.0.6",
"resolved": "https://registry.npmjs.org/pacote/-/pacote-17.0.6.tgz",

View file

@ -14,7 +14,6 @@
"autoprefixer": "^10.4.17",
"nuxt": "^3.8.2",
"nuxt-aos": "^1.2.2",
"nuxt-delay-hydration": "^1.3.3",
"nuxt-icon": "^0.6.8",
"postcss": "^8.4.33",
"sass": "^1.70.0",