Getting Started

Internationalization (i18n)

Learn how to use internationalization in your email templates

Overview

Nuxt Email Renderer supports internationalization (i18n) when you have the @nuxtjs/i18n module installed in your project. This allows you to render email templates in different languages.

Prerequisites

To use i18n support in your email templates, you need to:

  1. Install @nuxtjs/i18n in your Nuxt project
  2. Configure @nuxtjs/i18n in your nuxt.config.ts

Installation

npm install @nuxtjs/i18n

Configuration

Add @nuxtjs/i18n to your Nuxt config:

nuxt.config.ts
export default defineNuxtConfig({
  modules: ["nuxt-email-renderer", "@nuxtjs/i18n"],
  i18n: {
    locales: [
      { code: "en", name: "English" },
      { code: "de", name: "Deutsch" },
      { code: "es", name: "Español" },
    ],
    defaultLocale: "en",
    vueI18n: "./i18n.config.ts",
  },
});

Create your i18n configuration file. @nuxtjs/i18n v10 resolves vueI18n inside the i18n/ directory (restructureDir):

i18n/i18n.config.ts
export default defineI18nConfig(() => ({
  legacy: false,
  locale: "en",
  messages: {
    en: {
      welcome: "Welcome",
      greeting: "Hello, {name}!",
      message: "This is a test email",
      button: "Click here",
    },
    de: {
      welcome: "Willkommen",
      greeting: "Hallo, {name}!",
      message: "Dies ist eine Test-E-Mail",
      button: "Hier klicken",
    },
    es: {
      welcome: "Bienvenido",
      greeting: "¡Hola, {name}!",
      message: "Este es un correo electrónico de prueba",
      button: "Haz clic aquí",
    },
  },
}));
Nuxt Email Renderer reads the messages from this file at build time. A config file next to nuxt.config.ts still works, and so does a plain object export without defineI18nConfig.

When vueI18n is not used, locale messages can also be loaded from locales[].file or locales[].files. JSON, YAML, and YML files are supported, including multiple files per locale and files in Nuxt layers.

Using i18n in Email Templates

Once configured, you can use the $t function in your email templates just like you would in regular Vue components:

emails/WelcomeEmail.vue
<script setup lang="ts">
const props = defineProps<{
  name: string;
}>();
</script>

<template>
  <EHtml>
    <EHead />
    <EBody>
      <EContainer>
        <EHeading>{{ $t("welcome") }}</EHeading>
        <EText>{{ $t("greeting", { name: props.name }) }}</EText>
        <EText>{{ $t("message") }}</EText>
        <EButton href="https://example.com">
          {{ $t("button") }}
        </EButton>
      </EContainer>
    </EBody>
  </EHtml>
</template>

Rendering with Different Locales

To render an email template in a specific locale, pass the locale option to the renderEmailComponent function:

server/api/send-email.post.ts
export default defineEventHandler(async (event) => {
  const body = await readBody(event);

  // Render the email in German
  const { html } = await renderEmailComponent(
    "WelcomeEmail",
    { name: "Hans" },
    {
      locale: "de",
      pretty: true,
    },
  );

  // Send the email...
  return { success: true };
});

How It Works

The module detects @nuxtjs/i18n and loads its configured messages during build time. It stores the messages and default locale in private runtime config, then creates a new i18n instance when rendering an email. Pass locale to renderEmailComponent to choose the email language; the renderer does not read the locale from the request event.

Nuxt Email Renderer does not add its copy of the messages to runtimeConfig.public.i18n. The @nuxtjs/i18n module continues to manage its own public config.

Limitations

  • Build-time messages: Messages are loaded during build time, so dynamic message loading is not supported.
  • Server-side only: i18n support only works when rendering emails on the server using renderEmailComponent.
  • No composables: You cannot use useI18n() or other i18n composables in email templates. Only the $t function is available in templates.

Example

Check out the i18n test fixture in the repository for a complete working example.

Copyright © 2026