IntlProvider not injecting ids on FormattedMessage

609 Views Asked by At

I'm following the guide here to setup automatic id generation for FormattedMessage components under the IntlProvider but it doesn't appear to be injecting the ids at run time since I'm receiving this error in the console. enter image description here

 An `id` must be provided to format a message. You can either:
1. Configure your build toolchain with [babel-plugin-formatjs](https://formatjs.io/docs/tooling/babel-plugin)
or [@formatjs/ts-transformer](https://formatjs.io/docs/tooling/ts-transformer)

I started with a new react app from create-react-app and added react-intl from there and following the installation instructions on the formatjs.io site.

babel.config.json

{
    "plugins": [
      [
        "formatjs",
        {
            "idInterpolationPattern": "[sha512:contenthash:base64:6]",
            "ast": true
        }
      ]
    ]
  }

package.json

{
  "name": "react-intl-test",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@types/node": "^16.18.23",
    "@types/react": "^18.0.35",
    "@types/react-dom": "^18.0.11",
    "babel-plugin-formatjs": "^10.4.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-intl": "^6.3.2",
    "react-scripts": "5.0.1",
    "typescript": "^4.9.5"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "extract": "formatjs extract src/**/*.ts* --ignore=**/*.d.ts --out-file lang/en-US.json --id-interpolation-pattern [sha512:contenthash:base64:6]",
    "compile": "formatjs compile lang/en-US.json --ast --out-file src/compiled-lang/en-US.json",
  },
  "eslintConfig": {
    "extends": "react-app",
    "plugins": [
      "formatjs"
    ],
    "rules": {
      "formatjs/no-offset": "error"
    }
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@babel/core": "^7.21.4",
    "@formatjs/cli": "^6.0.4",
    "babel-plugin-formatjs": "^10.4.0",
    "eslint": "^8.38.0",
    "eslint-plugin-formatjs": "^4.9.1"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react"
  },
  "include": [
    "src"
  ]
}

App.tsx

import React from 'react';
import './App.css';
import { FormattedMessage } from 'react-intl';


function App() {
  
   return (
    <div className="App">
      hello <FormattedMessage description="other part of hello world" defaultMessage='world'></FormattedMessage>
    </div>
  );
}

export default App;

en-US.json

{
  "Oup1TP": [
    {
      "type": 0,
      "value": "world"
    }
  ]
}

I can enable the enforceId lint rule and it's looking for the same Id that is loaded from the en-US.json file.

I've tried lots of variations of eslint rules, switched to the .babelrc file, changed up the hash. If I manually put in an id on the formatted message or put the id from the compiled file, the app works just fine.

My understanding is that the FormattedMessage components under the IntlProvider with this setup should have the Id injected when I run. I'm basing this off the documentation recommending against manually adding ids in favor of automatic generation and this fallback logic specified in the documentation.

1

There are 1 best solutions below

1
On BEST ANSWER

I suspect the problem is in the way create-react-app is set up. All the tools come preconfigured. I don't think you can just install Babel plugins. You'd have to npm run eject to be able to use them.