index.js
function ial(app, opts) {

  /**
   * Lazily creates an i18n.
   *
   * @api public
   */

  Object.defineProperty(app.context, 'i18n', {
    get: function () {
      if (this._i18n) {
        return this._i18n
      }

      const i18n = new I18n(opts)
      i18n.request = this.request
      this._i18n = i18n

      // merge into ctx.state
      this.state.i18n = i18n
      registerMethods(this.state, i18n)

      debug('app.ctx.i18n %j', i18n)
      return i18n
    }
  })

  Object.defineProperty(app.request, 'i18n', {
    get: function () {
      return this.ctx.i18n
    }
  })

  return function i18nMiddleware(ctx, next) {
    ctx.i18n.whitelist.some(key => {
      const customLocaleMethod = typeof key === 'function'
        && ctx.i18n.setLocale(key.apply(ctx))
      if (customLocaleMethod || ctx.i18n[SET_PREFIX + key]()) return true
    })
    return next()
  }
}
function ial(app, opts) {

  /**
   * Lazily creates an i18n.
   *
   * @api public
   */

  Object.defineProperty(app.context, 'i18n', {
    get: function () {
      if (this._i18n) {
        return this._i18n
      }

      const i18n = new I18n(opts)
      i18n.request = this.request
      this._i18n = i18n

      // merge into ctx.state
      this.state.i18n = i18n
      registerMethods(this.state, i18n)

      debug('app.ctx.i18n %j', i18n)
      return i18n
    }
  })

  Object.defineProperty(app.request, 'i18n', {
    get: function () {
      return this.ctx.i18n
    }
  })

  return function i18nMiddleware(ctx, next) {
    ctx.i18n.whitelist.some(key => {
      const customLocaleMethod = typeof key === 'function'
        && ctx.i18n.setLocale(key.apply(ctx))
      if (customLocaleMethod || ctx.i18n[SET_PREFIX + key]()) return true
    })
    return next()
  }
}
Internationalization and Localization