digitalfabrik/integreat-app

View on GitHub
web/src/utils/BrowserLanguageDetector.ts

Summary

Maintainability
A
1 hr
Test Coverage
F
15%
import { LanguageDetectorModule } from 'i18next'

import safeLocalStorage, { I18N_LANGUAGE_KEY } from './safeLocalStorage'

const languageDetector: LanguageDetectorModule = {
  type: 'languageDetector',
  init: () => undefined,
  // Returns array of ISO-639-2 or ISO-639-3 language codes
  detect: () => {
    const bcp47Tags: string[] = []

    const localStorageLanguage = safeLocalStorage.getItem(I18N_LANGUAGE_KEY)

    if (localStorageLanguage) {
      bcp47Tags.push(localStorageLanguage)
    }

    // Adapted from:
    // https://github.com/i18next/i18next-browser-languageDetector/blob/a84df47faf3603ece04bc224e8e0f6f0ca1df923/src/browserLookups/navigator.js
    if (typeof navigator !== 'undefined') {
      // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition,@typescript-eslint/strict-boolean-expressions
      if (navigator.languages) {
        // chrome only; not an array, so can't use .push.apply instead of iterating
        for (let i = 0; i < navigator.languages.length; i += 1) {
          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
          bcp47Tags.push(navigator.languages[i]!)
        }
      }

      // IE only
      const userLanguage = (navigator as { userLanguage?: string }).userLanguage
      if (userLanguage) {
        bcp47Tags.push(userLanguage)
      }

      if (navigator.language) {
        bcp47Tags.push(navigator.language)
      }
    }

    return bcp47Tags.length > 0 ? bcp47Tags : undefined
  },
  cacheUserLanguage: (language: string) => {
    safeLocalStorage.setItem(I18N_LANGUAGE_KEY, language)
  },
}

export default languageDetector