I18N

Internationalization support is done using the i18next library, the same the Amazon Alexa Node SDK uses.

Configuring the skill for I18N

To use it you need to configure your skill to use the I18NRenderer class instead of the default renderer class.

const Voxa = require('voxa');
const skill = new Voxa({ Model, variables, views, RenderClass: Voxa.I18NRenderer });

The framework takes care of selecting the correct locale on every alexa event by looking at the alexaEvent.request.locale property.

Changes in your views

The other change you will need is to define your views using the i18next translate format:

'use strict';

const views = (function views() {
  return {
    'en-us': {
      translation: {
        LaunchIntent: {
          OpenResponse: { tell: 'Hello! Good {time}' },
        },
        Question: {
          Ask: { ask: 'What time is it?' },
        },
        ExitIntent: {
          Farewell: { tell: 'Ok. For more info visit {site} site.' },
        },
        Number: {
          One: { tell: '{numberOne}' },
        },
        Say: {
          Say: { say: 'say' },
        },
        Random: { tell: ['Random 1', 'Random 2', 'Random 3'] },
      },
    },
    'de-de': {
      translation: {
        LaunchIntent: {
          OpenResponse: { tell: 'Hallo! guten {time}' },
        },
        Question: {
          Ask: { ask: 'wie spät ist es?' },
        },
        ExitIntent: {
          Farewell: { tell: 'Ok für weitere Infos besuchen {site} Website' },
        },
        Number: {
          One: { tell: '{numberOne}' },
        },
        Say: {
          Say: { say: 'sagen' },
        },
        Random: { tell: ['zufällig 1', 'zufällig 2', 'zufällig 3'] },
      },
    },
  };
}());

module.exports = views;

Variables

Variables should work mostly the same as with the DefaultRenderer, with the exception that variables will now get a locale key

'use strict';

/**
 * Variables for tests
 *
 * Copyright (c) 2016 Rain Agency.
 * Licensed under the MIT license.
 */

const Promise = require('bluebird');

const variables = {
  exitDirectiveMessage: function exitDirectiveMessage() {
    return ({
      text: 'Thanks for playing!',
      type: 'PlainText',
    });
  },
  exitCard: function exitCard() {
    return {
      type: 'Standard',
      title: 'title',
      text: 'text',
      image: {
        smallImageUrl: 'smallImage.jpg',
        largeImageUrl: 'largeImage.jpg',
      },
    };
  },
  exitArray: function exitArray() {
    return [{ a: 1 }, { b: 2 }, { c: 3 }];
  },
  time: function time() {
    const today = new Date();
    const curHr = today.getHours();

    if (curHr < 12) {
      return Promise.resolve('Morning');
    }
    if (curHr < 18) {
      return Promise.resolve('Afternoon');
    }
    return Promise.resolve('Evening');
  },

  site: function site() {
    return Promise.resolve('example.com');
  },

  count: function count(model) {
    return model.count;
  },

  numberOne: function numberOne(model, request) {
    if (request.request.locale === 'en-us') {
      return 'one';
    } else if (request.request.locale === 'de-de') {
      return 'ein';
    }

    return 1;
  },
};

module.exports = variables;