i18next / i18next-express-middleware

[deprecated] can be replaced with i18next-http-middleware
https://github.com/i18next/i18next-http-middleware
MIT License
207 stars 55 forks source link

How to combine two methods ? #206

Closed golubvladimir closed 4 years ago

golubvladimir commented 4 years ago

My config:

      order: ['header', 'path'],
      lookupPath: 'api/lng',
      lookupFromPathIndex: 1,
      lookupHeader: 'accept-language',

I have two axios requests: 1)

    const { auth, lang } = rootState;

    const result = await this.$axios.$get('/api/errors', {
      headers: {
        'Authorization': `bearer ${auth.token}`,
        'Accept-Language': `${lang.locale}`
      },
      params: {
        page: settings.page,
        perPage: settings.perPage
      }
    });

2)

    const { auth, lang } = rootState;

    const result = await this.$axios.$get(`/api/${ lang.locale }/menu`, {
      headers: {'Authorization': `bearer ${auth.token}`},
    });

server.js

api.get('/:lng/menu', authenticateToken, async (req, res) => {
    try {
      console.log(req.language); // ru-RU
...

api.get('/errors', authenticateAdminToken, async (req, res) => {
   try {
       console.log(req.language); // en

Why different results ?

golubvladimir commented 4 years ago

I have request, when changing language. The result is the same.

console.log(req.language); // ru-RU
jamuhl commented 4 years ago

'Accept-Language': ${lang.locale} !== lookupHeader: 'accept-language', it's case sensitive

golubvladimir commented 4 years ago

@jamuhl how to name of language file ? When I set debug true. I have watched this:

i18next::backendConnector: loading namespace translation for language lang-RU-RU.js failed [Error: ENOENT: no such file or directory, open 'C:\Users\v.golub\Documents\projects\adminnuxt\adminpanel\lang\json\lang-RU-RU.js.json'] {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path: 'C:\\Users\\v.golub\\Documents\\projects\\adminnuxt\\adminpanel\\lang\\json\\lang-RU-RU.js.json'
}
i18next::backendConnector: loading namespace translation for language lang-RU failed [Error: ENOENT: no such file or directory, open 'C:\Users\v.golub\Documents\projects\adminnuxt\adminpanel\lang\json\lang-RU.json'] {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path: 'C:\\Users\\v.golub\\Documents\\projects\\adminnuxt\\adminpanel\\lang\\json\\lang-RU.json'
}
i18next::backendConnector: loading namespace translation for language lang failed [Error: ENOENT: no such file or directory, open 'C:\Users\v.golub\Documents\projects\adminnuxt\adminpanel\lang\json\lang.json'] {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path: 'C:\\Users\\v.golub\\Documents\\projects\\adminnuxt\\adminpanel\\lang\\json\\lang.json'
}

My file look like: 'ru.json'

jamuhl commented 4 years ago

you can define that in the backend options, eg. https://github.com/i18next/i18next-node-fs-backend#backend-options (loadPath)

golubvladimir commented 4 years ago

@jamuhl It did not help

jamuhl commented 4 years ago

then something is wrong out of my sight...you will need to debug your code.

golubvladimir commented 4 years ago

@jamuhl

i18next config

i18next
  .use(i18nextMiddleware.LanguageDetector)
  .use(FilesystemBackend)
  .init({
    debug: false,
    fallbackLng: ['en'],
    preload: ["en", "ru"],
    detection: {
      order: ['header', 'path'],
      lookupPath: 'api/lng',
      lookupFromPathIndex: 1,
      caches: false,
      lookupHeader: 'Accept-Language'
    },
    backend: {
      loadPath: path.join(__dirname, '../lang/json/{{lng}}.json'),
      jsonIndent: 2,
    }
  });

errors request:

export const actions = {
  async getErrors({rootState, state, commit}, settings) {
    const { auth, lang } = rootState;

    const result = await this.$axios.$get('/api/errors', {
      headers: {
        'Authorization': `bearer ${auth.token}`,
        'Accept-Language': `${lang.locale}`
      },
      params: {
        page: settings.page,
        perPage: settings.perPage
      }
    });

errors handler

app.use('/api', api);

api.get('/errors', authenticateAdminToken, async (req, res) => {
   try {
      console.log(req.language); // errors

Why don't I get the value from the header ?

jamuhl commented 4 years ago

you will need to debug it...what do I know from reading some code snippets...works on my machine

golubvladimir commented 4 years ago

@jamuhl I created codesandbox https://codesandbox.io/s/nervous-wind-uxjup?fontsize=14&hidenavigation=1&theme=dark

On GET: https://uxjup.sse.codesandbox.io/api/test-header, with Accept-Language header in console test-HEADER On GET: https://uxjup.sse.codesandbox.io/api/ru/url-param, in console ru.

My question: Why don't I get the value from the header ? I set header to first.

golubvladimir commented 4 years ago

@jamuhl I fixed it, in req.headers all headers in smaller case.

golubvladimir commented 4 years ago

I have error, bacause Chrome by default add to headers Accept-Language this value -

Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7

How does the plugin work in this case?

golubvladimir commented 4 years ago

In console ru-RU.

jamuhl commented 4 years ago

That detector wasn't added by myself but looking at the code it seems to support that by sorting lng by prio and picking the one with highest prio: https://github.com/i18next/i18next-express-middleware/blob/master/src/languageLookups/header.js#L14