Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

agodoo's avatar

Vuejs 3 using i18n translation inside "script setup"

I have a Laravel + Inertiajs + Vue 3 with Vite I used Quasar framework so in one vue file I have a Quasar table. Now I need to translate the column labels.

<AuthenticatedLayout>
    <template #header>
      <div>
        <q-toolbar class="q-gutter-sm">
          <Link :href="route('list-utenti')" type="button" class="float-right"><q-btn flat round dense icon="people" /></Link>
          <div class="text-subtitle1">{{ $t('utenti.pagetitle')}}</div>
        </q-toolbar>
      </div>
    </template>

    <div class="q-py-md q-gutter-sm">
      <Link :href="route('register')" type="button" class="float-right"><q-btn icon="add_box" color="white" text-color="text-grey-7" :label="$t('utenti.btn_new')"></q-btn></Link>
    </div>
    <div class="q-py-xl">
      <q-table
        title=""
        :rows="users"
        :columns="columns"
        row-key="id"
      >
        <template v-slot:body-cell-actions="props">
          <q-td :props="props">
            <q-btn icon="mode_edit" @click="onEdit(props.row)"></q-btn>
            <q-btn icon="person_off" @click="onDelete(props.row)"></q-btn>
          </q-td>
        </template>
        <template v-slot:body-cell-email="props">
          <q-td :props="props">
            <strong>{{ props.value }} </strong>
          </q-td>
        </template>          
      </q-table>
    </div>
</AuthenticatedLayout>
As you can see in the template code, I configured i18n and I can correctly translate with {{ $t('utenti.pagetitle') }} when in template.

now this is the script part

<script setup>
  import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
  import { Inertia } from '@inertiajs/inertia';
  import { Link } from '@inertiajs/inertia-vue3';
  import { computed, ref} from '@vue/reactivity';
  import { Quasar, useQuasar } from 'quasar';

  const props = defineProps({
      page_description : String,
      title: String,
      numero_record: Number,
      users: Array
  });

  const columns = [
    {
      name: 'id',
      required: true,
      label: 'id',
      align: 'left',
      field: row => row.id,
      format: val => `${val}`,
      sortable: false
    },
    { name: 'name', align: 'left', label: translated_name, field: 'name', sortable: true},
    { name: 'email', align: 'left', label: 'e-mail', field: 'email', sortable: false},
    { name: 'ruolo', align: 'left', label: 'ruolo', field: 'ruolo', sortable: true},
    { name: 'listino_grossista_visible', align: 'center', label: 'list. grossista', field: 'listino_grossista_visible', sortable: true},
    { name: 'enabled', align: 'center', label: 'Attivo', field: 'enabled', sortable: true},
    { name: 'actions', align: 'center', label: 'Azioni'}
  ]

  const onEdit = (row) => {
    Inertia.post(route('edit-utente'),
      { row } ,
      { onBefore: () => confirm('Vuoi veramente modificarlo?')}
    )
  }

  const onDelete = (row) => {
    alert('DELETE ' + row.email);
  }
</script>

I would like to use in some way $t to get the correct translation for the grid columns labels (for example 'translated_name' but I don' understand how I can do it as it is in the script part and I can not use same as in template.

I probably understood that I need to add some computed properties but I didn't exactly figured out how. Consider I'm using composition api.

  const translated_name = computed(() =>  {
    return $t('utenti.nome')
  })

kind regards, Matt

0 likes
1 reply
oakydev's avatar

Hey!

After a bit of researching I found the following

<script setup>
	import { usei18n } from 'vue-i18n';
	const { t } = usei18n();
</script>

This will make t availble in your script tag and you can translate your keys. :D

Hope this helps with your problem.

Please or to participate in this conversation.