Hugo Gresse
Hugo Gresse

Reputation: 17909

i18next warn or lint on missing key for a language (not the fallbackLng)

My project is using i18next and react-i18next with success so far. No localize or server side involved.

Current setup:
- default & fallback language: en
- additional language: fr

I wanted to automate some things related to error checking:
1. Check that all key are translated in each defined language file
2. Either warn in dev env or lint for the ci/cd.

I've tried doing 1. with the following option:


    saveMissing: true,
    saveMissingTo:"all",
    missingKeyHandler: (ng, ns, key, fallbackValue) => {
        console.log(ng, ns, key, fallbackValue)
    },

    // other options
    resources: {
        en: {
            translations: enTranslation,
        },
        fr: {
            translations: frTranslation,
        },
    },
    fallbackLng: 'en',
    ns: ['translations'],
    defaultNS: 'translations',

    interpolation: {
        formatSeparator: ',',
    },

    react: {
        wait: true,
    }

I thought if I deleted a key from my French .json (to test that it works) it will be logged, but it did not, only if I delete both key.

Other solution tried:
1. "eslint-plugin-i18n-json" but it doesn't check what I needed, haven't found the right options/config
2. Option 2.

Do you have any link or solution to help? (except those involving a saas)

Upvotes: 6

Views: 9788

Answers (4)

Roman Lauryniuk
Roman Lauryniuk

Reputation: 11

I used react-i18next-lint - Simple CLI tool for check react-i18next keys in whole app which use regexp.

Add this command to package.json

npx react-i18next-lint -c ./config/react-i18next-lint.json

Config file:

{
  "rules": {
    "keysOnViews": "error",
    "zombieKeys": "disable",
    "misprintKeys": "disable",
    "deepSearch": "disable",
    "emptyKeys": "error",
    "maxWarning": "0",
    "misprintCoefficient": "0.9",
    "ignoredKeys": [],
    "ignoredMisprintKeys": [],
    "customRegExpToFindKeys": [ "(?<=\\$t\\(['\"])([A-Za-z0-9_\\-.]+)(?=['\"]\\))"]
  },
  "project": "./src/**/*.{html,ts,resx,js}",
  "languages": "./src/assets/i18n/en.json"
}

rule keysOnViews - handle the error of missing keys on view. For example, if you have a key on view, but it doesn't exist on language file.

custom regexp, in my case, describes finding keys on a view which looks like

$t('some.translate.key')

Upvotes: 1

Emre Hayırcı
Emre Hayırcı

Reputation: 19

In my use case, I just wanted the app to throw an error in specific environments. I added the following in my configuration and it worked for me.

  saveMissing: true,
  missingKeyHandler: (ng, ns, key, fallbackValue) => {
    throw new Error(`Key not found ${key}, ${ng}, ${ns}, ${fallbackValue}`);
  },

I hope it helps

My assumption about your case, console log statement didn't work because the key exists in your fallback language.

Upvotes: 0

Hugo Gresse
Hugo Gresse

Reputation: 17909

While @tudor answer work for eslint in javascript format, it wasn't in .json format. Here is the solution:

Plugin: eslint-plugin-i18n-json
Usage:

  1. Add the plugin to .eslintrc
    "extends": ["eslint:recommended", "plugin:i18n-json/recommended"],

  2. Add a new rules to .eslintrc that should contain all the required keys

    "rules": {
        "i18n-json/identical-keys": [2, {
            "filePath": {
                "admin.json": "../../../../src/languages/en.json",
            }
        }],
    }
    

    Note: For the require we need to go back 4 folders (from node_modules/eslint-plugin-i18n-json/src/util/require-no-cache.js) in order to get to our translation file.
    Since require will first try to resolve from the predefined __dirname. And the __dirname for require-no-cache.js is going to be ` node_modules/eslint-plugin-i18n-json/src/util.

  3. Add a new script to your package.json where it will check if all the key are existing (against the file from 2.)

    script: {
        "lint:i18n": "eslint src/**/languages/*.json"
    }
    

Source: https://github.com/godaddy/eslint-plugin-i18n-json/issues/31#issuecomment-604636886

Upvotes: 2

hiddenuser.2524
hiddenuser.2524

Reputation: 4988

You can use https://github.com/godaddy/eslint-plugin-i18n-json#i18n-jsonidentical-keys. Here's how:

Add this inside your eslintrc:

module.exports = {
  extends: ["plugin:i18n-json/recommended"],
  rules: {
    "i18n-json/identical-keys": [
      2,
      {
        filePath: path.resolve("translations/en.json")
      }
    ]
  }
};

and then run eslint with this options:

eslint --fix --ext .json --format node_modules/eslint-plugin-i18n-json/formatter.js translations/

This assumes the folder with translations is called translations (you should adapt the path).

Here is a codesandbox demonstrating that it works: https://codesandbox.io/s/friendly-minsky-9siu4

You can use the terminal to run npm run lint and you can play with the values inside translations/en.json and translations/de.json to check how it works.

Upvotes: 2

Related Questions