Jenos
Jenos

Reputation: 504

Nuxt-i18n : Retrieve and loop arrays from translation messages or json files

Please help. I am trying i18n with Nuxt 3 using @nuxtjs/i18n package and hit a road block retrieving arrays form translation documents as is. The value comes as abstract syntax tree using $tm, as below:

Whats expected is

[
      {
        "title": "Title 1",
        "description": "Description 1",
        "price": "Price 1"
      },
      {
        "title": "Title 2",
        "description": "Description 2",
        "price": "Price 2"
      }
    ]

but what i receive is

[
  {
    "title": {
      "type": 0,
      "start": 0,
      "end": 7,
      "loc": {
        "start": {
          "line": 1,
          "column": 1,
          "offset": 0
        },
        "end": {
          "line": 1,
          "column": 8,
          "offset": 7
        },
        "source": "Title 1"
      },
...
...
..

here is the sample code of the test page, with the issue

<i18n lang="json">
{
  "en": {
    "summary": [
      {
        "title": "Title 1",
        "description": "Description 1",
        "price": "Price 1"
      },
      {
        "title": "Title 2",
        "description": "Description 2",
        "price": "Price 2"
      }
    ]
  }
}
</i18n>
<template>
  <div>
    <div>
      <pre>{{ $tm('summary') }}</pre>
    </div>

  </div>
</template>

<script setup>
const { t, tm, rt } = useI18n()


</script>

Codesandbox reproduction

Can someone help how to properly retrive arrays and objects as is from translation messages? It used to work as expected in previous version of i18n with Nuxt 2 and $t

Thank you

Upvotes: 0

Views: 444

Answers (2)

Nawi
Nawi

Reputation: 81

The right way to do this is using the rt component

const { t, tm, rt } useI18n()

Your code seems to use local blocks in SFC, so the useScope must be set to "local"

const { t, tm, rt } useI18n({
useScope: "local"
})

The right way to loop in this new version (vue3 & Nuxt3) is using tm and rt.

<script setup>
const { t, tm, rt } = useI18n()
</script>

<template>
  <div>

    <div v-for="sum in tm('summary')" :key="sum.price">
      <pre>{{ rt(sum.title) }}</pre>
      <pre>{{ rt(sum.description) }}</pre>
      <pre>{{ rt(sum.price) }}</pre>
    </div>

  </div>
</template>

<i18n lang="json">
{
  "en": {
    "summary": [
      {
        "title": "Title 1",
        "description": "Description 1",
        "price": "Price 1"
      },
      {
        "title": "Title 2",
        "description": "Description 2",
        "price": "Price 2"
      }
    ]
  }
}
</i18n>

Upvotes: 0

It is not possible anymore to obtain the original JSON using the i18n lib.

This issue and this piece of the documentation are about your question as well.

The translation API like $t and t function that return string only. Object and array values are no longer returned.

If this behaviour is what you want, you should store it in a cache and retrieve it when you want.

If you want to retrieve the translated locales using i18n you can achieve that in two ways:

  <template>
    <div>
      <NuxtLink :to="switchLocalePath('de')"> DE </NuxtLink>
      <NuxtLink :to="switchLocalePath('en')"> EN </NuxtLink>


      <div v-for="(item, index) in summary" :key="index">
        <h1> 1st approach: {{ t(`summary[${index}].title`) }}  </h1>
        <h1> 2nd approach: {{ item.title.body.static }}</h1>
      </div>
    </div>
  </template>
  
  <script setup>
  
  const { t, tm } = useI18n()
  const summary = tm('summary') 
  
  </script>

Upvotes: 0

Related Questions