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:

i18n.config.ts
export default {
  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í",
    },
  },
};
Do not wrap the export with defineI18nConfig when using it with Nuxt Email Renderer, as the configuration needs to be loadable on the server side.

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 };
});

Passing Event Context

If you want the i18n configuration to be extracted from the current request context, you can pass the event parameter:

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

  // The locale will be determined from the event context if available
  const html = await renderEmailComponent(
    "WelcomeEmail",
    { name: body.name },
    {
      event, // Pass the event context
      locale: body.locale, // Optional: override locale
      pretty: true,
    },
  );

  return { success: true };
});

How It Works

Nuxt Email Renderer uses multiple approaches to set up i18n for email rendering:

  1. Runtime Config Approach: The module extracts i18n configuration from your Nuxt app and stores it in the runtime config. When rendering emails, it creates a new i18n instance with the messages from your configuration.
  2. Event Context Approach: If you pass the H3 event context, the renderer tries to extract i18n information from the request context.

The module automatically detects if @nuxtjs/i18n is installed and loads your i18n messages during build time, making them available for server-side email rendering.

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.