Skip to content

I18n

Usage

@saflib/vue depends on Vue I18n, but with a twist: strings are looked up by value, not key. So instead of:

html
<h1>{{ $t("hello.world") }}</h1>

You should use:

vue
<script setup lang="ts">
import { useReverseT } from "../../i18n.ts";
import { hello } from "./strings.ts";
const { t } = useReverseT();
</script>

<template>
  <h1>{{ t(hello.world) }}</h1>
</template>

See this i18n.ts section for more info on how to set that up.

Why?

Looking up strings by value provides a few key benefits:

  • In development, it's easier to find the value; you can use IDE features to jump to the string value quickly.
  • When creating the value-to-key mapping, duplicate strings are easy to find and warn about.
  • Most importantly, TypeScript highlights when pages are not using the correct key so you don't waste time checking if a string renders correctly.

Because behind the scenes the lookups are still using vue-i18n's t function, you still get all the vue-i18n features.

The reverse-t function also handles flat objects, for seamless binding to HTML elements.

ts
// strings.ts
export const hello = {
  label: "hello label",
  placeholder: "hello placeholder",
  "aria-label": "hello aria label",
  role: "button",
  text: "hello text",
};
vue
<script setup lang="ts">
import { useReverseT } from "../../i18n.ts";
import { hello } from "./strings.ts";
const { t } = useReverseT();
</script>

<template>
  <!-- All strings are translated! -->
  <v-text-field v-bind="t(helloForm)" />
</template>

Strings objects can be any nesting of objects, arrays, and strings; the reverse-t function will properly map them to their correct Vue I18n keys.