Select element to get locale in nuxt with nuxt-i18n
Asked Answered
B

3

5

I use nuxt-i18n nuxt-i18n documentation link to get different locales on my website like that :

<nuxt-link v-for="locale in $i18n.locales"
             v-if="locale.code !== $i18n.locale"
             :key="locale.code"
             :to="switchLocalePath(locale.code)"
             class="locales white--text"
  >{{ locale.code }}
  </nuxt-link>

And it works perfectly fine but i want to transform this code to render in a select element:

<select v-model="selected" class="locales white--text" @change=" ??? ">
    <option disabled value="">{{ $i18n.locale }}</option>
    <option v-for="locale in $i18n.locales" :key="locale.code">{{ locale.code }}</option>
  </select>

Locales strings appears well but i don't dind a solution to launch the switchLocalePath function on change. Is there a proper way to do that with nuxt (vue.js) ?

Balduin answered 18/7, 2018 at 15:38 Comment(10)
this.$router.push(this.switchLocalePath(locale.code));Grory
but this has to be in each option element ?Balduin
My bad, you should use selected value instead (in @change handler).Grory
so selected would be in "methods" of vue ? but i can't access "locale.code" outside of the loop. Could u write an example because im a bit lost on this ?Balduin
I said you need to use value of selected (model) in your @change function, as it's the only thing available on select level; locale.code is property of corresponding option element.Grory
That works perfectly like that indeed. thx for ur patience.Balduin
How did you succeed to install and set up nuxt-i18n ? (here is my question if you can answer: #52534808)Cincture
<select v-model="selected" :style="{ 'background-image': 'url(' + '/main_icons/drop-down-arrow-black.png' + ')', 'background-position': 'right' }" style="color:black; width:3rem" class="select__lang" @change="changeLocale()"> <option :value="selected" selected>{{ $i18n.locale }}</option> <option v-for="locale in $i18n.locales" v-if="locale.code !== $i18n.locale" :key="locale.code" >{{ locale.code }}</option> </select> and in my script i have this method : changeLocale() { this.$router.push(this.switchLocalePath(this.selected)); }Balduin
Hi, does your application have a simple base URL http://localhost:3000/? For me the switcher works only in this case, but when I have nested roots in my Nuxt application, the switcher does not work. Do you have an idea why? I have posted a question about itCincture
you should post the answer from comment to a formatted answerOneiromancy
T
8

Here you are, the dropdown list and the onChange method:

 <select v-model="selectedValue" @change="onChange(selectedValue)">
        <option disabled value>Please select one</option>
        <option
          v-for="(locale, index) in $i18n.locales"
          :key="index"
          :value="locale.code"
        >{{locale.name}}</option>
      </select>
 methods: {
    onChange(event) {
      this.$router.replace(this.switchLocalePath(event));
    }
  }

If you want to check working I have build a CodeSandox Nuxt working here:

https://codesandbox.io/embed/codesandbox-nuxt-1bhug?fontsize=14&hidenavigation=1&theme=dark

Tribunal answered 19/11, 2019 at 15:40 Comment(1)
I don't understand how come the question gets more upvotes? The solution works and it is the only solution for the question. People are strange.Curtice
P
1

Also there is no need to use the router to change the locale, the API can be used too using this.$i18n.setLocale(locale)

  <select v-model="activeLang" @change="changeLang" name="lang" id="">
    <option
      :selected="locale === activeLang"
      v-for="locale in locales"
      :key="locale"
      :value="locale"
    >
      {{ locale }}
    </option>
  </select>

changeLang(event) {
  this.$i18n.setLocale(event.target.value);
}

CodeSandbox here

Peephole answered 29/12, 2020 at 17:36 Comment(0)
E
0

In the first step, do the following first

// nuxt.config.js, inside nuxt-i18n module

locales: [
  { code: 'ar', iso: 'ar', file: 'ar/app.js', dir: 'rtl' },
  { code: 'en', iso: 'en-US', file: 'en/app.js', dir: 'ltr' },
  { code: 'fr', iso: 'fr-FR', file: 'fr/app.js', dir: 'ltr' },
],

Then create a plugin in the code and enter the following code

// plugins/ltr-rtl.js

export default function({ app }, inject) {
  const dir = () => app.i18n.locales.find((x) => x.code === app.i18n.locale)?.dir;
  inject( 'dir', dir);
}

And in the last step

<!-- layouts/default.vue -->

<div id="app" :dir="$dir()">
  My app here...
</div>
Equiprobable answered 7/3, 2022 at 16:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.