I have a web application built with ReactJS, react-scripts (webpack), Monaco Editor, and react-monaco-editor. By default, the context menu is in English:
In the hover window, View Problem, Quick Fix, etc. are also in English.
Now, I would like to localize these keywords to Chinese, does anyone know how to do it?
PS 0: I have searched similar issues such as https://github.com/microsoft/monaco-editor/blob/main/samples/browser-amd-localized/index.html, but I don't know how to configure (e.g., require.config) in a project with webpack and react-monaco-editor.
PS 1: Here is a working sample with react-monaco-editor: https://codesandbox.io/p/sandbox/goofy-rgb-q525mq?file=%2Fsrc%2FApp.js%3A16%2C20. The code calling react-monaco-editor is as follows, which is similar to the way of calling react-monaco-editor in my code.
<MonacoEditor
width="800"
height="600"
language="javascript"
value={code}
options={options}
onChange={this.onChange}
editorDidMount={this.editorDidMount}
/>
Edit 1: Thanks to @blutorange and @VonC, the demo of blutorange in codesandbox does work. I tried to make it work in my code. I put import AAA in my files before the import of monaco-editor and react-monaco-editor. I can see that After setLocaleData is printed in the console, but the keywords of the editor are still in English. Additionally, I use dva in the project. The follows is src/index.tsx:
import './AAA';
import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';
import dva from 'dva';
import './index.css';
import router from './router';
import AuthModel from './models/auth';
import SubscribtionModel from './models/subscription';
import AppModel from './models/app';
import SpreadsheetModel from './models/spreadsheet';
import UsageModel from './models/usage';
import AiModel from './models/ai';
import SettingsModel from './models/settings';
import { initializeIcons } from 'office-ui-fabric-react/lib/Icons';
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import zh from './i18n/locales/zh.json';
import en from './i18n/locales/en.json';
function patchOfficeExtension() {
// https://stackoverflow.com/questions/53327711/how-to-add-a-polyfill-to-support-finally-in-edge
//@ts-ignore
OfficeExtension.Promise.prototype.finally = /* Promise.prototype.finally || */ {
finally(fn: any): any {
const onFinally = (cb: any) => OfficeExtension.Promise.resolve(fn()).then(cb);
// @ts-ignore
return this.then(
(result: any) => onFinally(() => result),
(reason: any) => onFinally(() => OfficeExtension.Promise.reject(reason)),
);
},
}.finally;
// tslint:enable
}
// https://chat.openai.com/c/06d8c247-6107-463f-80a9-6b571ee23f88
i18n.use(initReactI18next).init({
lng: 'zh',
// lng: 'en',
resources: {
en: { translation: en },
zh: { translation: zh },
},
fallbackLng: 'en',
// interpolation: { escapeValue: false }
});
//@ts-ignore
//import createLoading from 'dva-loading';
initializeIcons();
// 1. Initialize
const app = dva();
//app.use(createLoading());
// 2. Plugins
// app.use({});
// 3. Model
//@ts-ignore
app.model(AuthModel);
app.model(SubscribtionModel)
app.model(AppModel);
app.model(SpreadsheetModel);
app.model(UsageModel);
app.model(AiModel);
app.model(SettingsModel);
// 4. Router
//@ts-ignore
app.router(router);
// 5. Start
app.start('#root');
Here is the updated webpack.config.js:
const WEBPACK = require('webpack');
const PATH = require('path');
const MonacoWebpackPlugin = require('monaco-editor-esm-webpack-plugin');
module.exports = {
resolve: {
extensions: ['.js', '.jsx']
},
context: __dirname,
entry: {
app: ['./src/index.jsx'] // app: ['./MY_FOLDER_INPUT/MY_FILE_INDEX.jsx']
},
output: {
path: PATH.join(__dirname, '/MY_FOLDER_OUTPUT'),
filename: 'index.js'
},
module: {
rules: [
{
test: /\.js/,
enforce: 'pre',
include: /node_modules[\\\/]monaco-editor[\\\/]esm/,
use: MonacoWebpackPlugin.loader
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
},
plugins: [
new MonacoWebpackPlugin()
]
};
Could you tell how I could detect precisely the order of imports? I tried to use source-map-explorer, it gives a map as follows, but i cannot even find AAA:



Check first if a webpack's plugin for monaco editor like
monaco-editor-nlswould be enough for your use case.You would need modify the
editorDidMountfunction in your React component to also set the locale data.Following its "Using" section example, that would be for you:
The
setLocaleDatais called in theeditorDidMountfunction to set the locale data after the Monaco Editor instance has been created. In your case, as you are usingreact-monaco-editor, the editor instance is created automatically by theMonacoEditorcomponent, and you get that instance in theeditorDidMountfunction.As commented, it is not enough on its own.
Try adding monaco-editor-esm-webpack-plugin (
npm install monaco-editor-esm-webpack-plugin)And update your
webpack.config.js:In the
pluginsarray, you see nownew MonacoWebpackPlugin()with some options. In thelanguagesarray, you should list the languages you want to use in your editor. In thefeaturesarray, you can enable additional editor features.In your main script file, you should be able to import the locale data from
monaco-editor-nlsand set the locale data using thesetLocaleDatafunction.blutorange adds in the comments:
That means, to ensure
setLocaleDatais called before the Monaco Editor loads, you might want to try calling it in a higher level component or as early as possible in your application's entry point file.Your entry point file should include:
Here,
setLocaleDatawould be called before yourAppcomponent (which presumably contains theMonacoEditorcomponent) is imported and used. The Monaco Editor is likely to be imported for the first time in yourAppcomponent or in a component withinApp, ensuringsetLocaleDatais called before any Monaco related imports.Do update your webpack configuration to use the
monaco-editor-esm-webpack-pluginas outlined previously.blutorange adds in the comments:
That means: make sure all your packages are up-to-date:
Then try and modify how you import
monaco-editorandreact-monaco-editorand where you callsetLocaleData. That is tricky because you cannot control howreact-monaco-editorimportsmonaco-editorinternally.Instead of using
setLocaleDataineditorDidMountor the entry point file, try using it in a separate module that you import before you importmonaco-editor. That would ensuresetLocaleDatais called beforemonaco-editoris imported.Define a separate module (let's call it
set-locale.js):And use it in your component file:
That approach attempts to ensure
setLocaleDatais called beforemonaco-editoris imported.blutorange also points out in the comments:
monaco-editor/reactwhich completely sidesteps the issue by not bundling monaco editor whatsoever but just loads it from a CDN at runtime.npm install @monaco-editor/reactThat is a good point.
@monaco-editor/reactis indeed another wrapper for Monaco Editor that might suit your needs better.That means, on that last point, you would not have to deal with webpack configurations for bundling the editor yourself.
To localize the editor with this package, you would have to find a way to load the locale data after the editor is loaded from the CDN.
See
loader-config