JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://v1.vuejs.org/js/vue.js"></script>
<div id="app">
</div>

JavaScript

const locale_translations = {
  /*
  'es': {
    'hello': 'hola'
  }
  */
}

var fetch = function (locale, key) {
  if (! locale) return key;

  var translations = locale_translations[locale]

  if (translations && key in translations) {
    return translations[key];
  }

  // key not found, fall back from dialect translations

  if (locale.indexOf('_') > -1) {
    return fetch(locale.substr(0, locale.indexOf('_')), key)
  }

  if (locale.indexOf('-') > -1) {
    return fetch(locale.substr(0, locale.indexOf('-')), key)
  }

  // key does not exist

  if (translations && window.console) {
    console.warn(`[vue-i18n] Translations exist for the locale '${locale}', but there is not an entry for '${key}'`)
  }

  return key
}

const translations = {
  'es': {
    'Hello world': 'Hola Mundo'
  },
  'fr': {
    'Hello world': 'Bonjour le monde'
  },
  'pirate': {
    'Hello world': 'Land ho!'
  }
}

Vue.use({
  install: function (Vue, translations = {}) {

    Object.keys(translations).forEach(function (locale) {
      locale_translations[locale] = translations[locale]
    })

    Vue.directive('locale', {
      params: ['key', 'replace'],

      update: function (locale) {
        var translated_substrings = this.vm.$t(this.params.key, this.params.replace).split('|');

        var children = this.el.children;

        for (var i = 0; i < children.length; i++) {
          if (translated_substrings[i]) {
            children[i].innerText = translated_substrings[i];
          }
        }
      }
    })

    Vue.prototype.$t = function (key, replacements = {}) {
      var locale = replacements['locale'] || this.$root.locale

      var translation = fetch(locale, key)

      return translation.replace(/\{\w+\}/g, function (placeholder) {
        var key = placeholder.replace('{', '').replace('}', '')

        if (replacements[key] !== undefined) {
          return replacements[key]
        }

        return placeholder
      })
    }

    Vue.filter('translate', function...