Problems applying Customised MFE libraries (eg "frontend-platform") to a production Open edX platform (using "tutor local")

Hello everyone.

I have been trying to make some modifications to the frontend-platform part of the MFEs so it will also support the Greek Language “el” (for the time being only a handful of languages are supported, I think just 14 of them), as, our platform runs in Greece in Greek language and without it we cannot keep up with the new Open Edx releases after tutor became the default installation method and MFEs are being used by default instead of the old django/mako templates in certain parts of the platform.

The changes needed to be made are minimal, just some minor additions to 3-4 files in the frontend-platform library.

After I bindmounted the forked MFEs’ code (eg the Learning MFE to my tutor dev installation) and edited the frontend-platform files directly inside the node_modules/@edx/frontend-platform path where they were installed, the Greek language worked without problems, but it seems impossible to transfer the changes to our “tutor local” open edx installation which we’ll use for our production platform.

First, I tried to use the following tutorial from here:

So I forked the frontend-platform to be able to make my tutor dev instalation use the forked one (so to edit its original code instead of the installed library inside node-modules/@edx/frontend-platform of each MFE), but it didn’t work due to some errors ending up in ignoring my “module.config.js” and using the locally installed frontend-platform inside each MFE’s node_modules.

I did the test with frontend-app-learning bindmounted to my tutor dev…

My “module.config.js” content is this:

module.exports = {
  localModules: [
    { moduleName: '@edx/frontend-platform', dir: '../src/frontend-platform', dist: 'dist' },

When I run “npm install && npm run build” it appears to be completed with just some warnings, although one of them seems to contain an error:

WARNING in ./node_modules/react-responsive/dist/react-responsive.js
Module Warning (from ./node_modules/source-map-loader/index.js):
(Emitted value instead of an instance of Error) Cannot find source file 'webpack:///dist/react-responsive.js': Error: Can't resolve './webpack:///dist/react-responsive.js' in '/home/user/WORK/PEK/OPENEDXREPOS/TMP/frontend-app-learning/node_modules/react-responsive/dist'
 @ ./node_modules/@edx/paragon/dist/index.js 106:0-102 106:0-102 106:0-102 106:0-102
 @ ./src/course-home/progress-tab/ProgressTab.jsx
 @ ./src/index.jsx 21:0-65 91:46-57

At the end I get this message: “webpack 5.50.0 compiled with 3 warnings in 29774 ms

Since it seems to not produce any errors I then try to mount the frontend-app-learning with “tutor dev start learning --mount=.” but I get the error trace shown in the following file:

That wasn’t a big problem though since the changes I wanted to make were minimal so I thought of just making the changes to my forked frontend-platform, pushing it to my github repo and then creating and enabling a tutor plugin with a “mfe-dockerfile-post-npm-install” patch to make my “tutor local” open edx platform use frontend-platform from my github repo instead of the original, following these steps from here:

My tutor plugin’s code is very simple as it’s shown here:
(it actually shows the path to the original frontent-platorm by open edx but, before trying that, I used my own repo)

from tutor import hooks

RUN npm install '@edx/frontend-platform@git+'

This produced errors (when I used my own repo) and failed to even continue with the “tutor local quickstart” installation.

The error trace is shown here:

To eliminate the possibility that I had errors in my changes of the frontend-platform library (since I could not test the changes before applying them to production for the reasons I explained firstly above), I tried to use the original repo of frontend-platform from github (as shown on the plugin code I have quoted right above), but I kept getting the same errors, so it wasn’t my changes that produced the errors but the method of applying them to the platform.

I have even tried using the exact same examples as shown in the help, using the following in my plugin:

First I tried to aply the original frontend-component-header from the npm repo:

RUN npm install '@edx/frontend-component-header@npm:@edx/frontend-component-header-edx@latest'

And then the frontend-component-footer from its github repo:

RUN npm install '@edx/frontend-component-footer@git+'

(Actually, there is an error I think in this step as it is shown in the help, the second part directs to the “frontend-component-header” instead of the “frontend-component-footer”, I believe this must be corrected. Although I tried both and none worked with similar errors)…

Again, the errors are shown in the following corresponding files:

Because it’s very important for us to be able to use the new releases in our native language, I would really appreciate some help on how to overcome those problems and also know if it’s something I am doing wrong or there is something wrong with the method of editing those components and applying them to the platform.

It would be very important and helpful for anyone who needs to make certain changes to the MFEs and their libraries, to be able to apply those changes to their production platform with ease and without such errors or too complicated steps.

For the record: I have no problem editing one or more of the actual MFEs (eg the Learning MFE) and applying them to the production platform (tutor local open edx installation) by changing the value which contains their source repo (eg: MFE_LEARNING_MFE_APP).
To my knowledge so far, the problem appears only with such libraries as the “frontend-platform” that are used by those MFEs and are installed inside each MFE’s node_modules.

Moreover, I can make a PR with my changes on the frontend-platform for including the Greek language (el) but even if my PR will be accepted and included to following versions, I believe this would take time and I’d prefer for the time being a solution where I can apply these changes myself instead of waiting for the next releases, as it will be much harder to migrate our data from Lilac to the latest future open edx release.

The machine I am using for my tests has the following versions of tutor, docker, docker-compose, docker compose, in case they are of importance:

tutor, version 14.1.0
Docker version 20.10.21, build baeda1f
docker-compose version 1.29.2
Docker Compose version v2.6.0

Thank you in advance for any help on this matter! I hope it’s something trivial!

@regis @arbrandes @mrtmm @djoy

1 Like

Hey @Dimitris_Angelakis,

You’re hitting some of the difficulties in using Tutor to develop MFEs locally. For the moment, most frontend developers still use the devstack, and that is what I suggest you do. The main advantage is being able to run an MFE outside a docker container (via regular npm start) and still have it connect to the rest of the Open edX instance. This allows you to configure webpack module aliases as instructed in the frontend-build README.

(@kmccormick has been hard at work at improving Tutor for development: you might want to try his quickdev plugin instead of the devstack.)

This doesn’t solve the issue of bringing the change into Tutor, of course. More on this below.

You’re on the right track regarding using your own repositories. That is the easiest way to bring changes into Tutor.

However, I don’t recommend a manual install of the latest versions of any npm packages unless you’re an experienced Open edX frontend developer; you’re very likely to run into the dependency errors you’re seeing. You should instead base your modifications on the exact version of a package that the version of the MFE you’re running installs, commit them, and then install that. This applies not only to frontend-platform, but also frontend-component-* and others.

You should also consider forking the MFE itself, and making the dependency modifications in its package.json. This will make it much easier to check that builds will run as intended. You can then point Tutor to your fork via:

tutor config save --set MFE_LEARNING_MFE_APP="{'name': 'learning', 'repository': '', 'port': 2000}"

Nice catch: there’s clearly a copy-paste error in there. PR opened to fix it. :+1:

1 Like

I’ve been following Dimitris’ issues pretty closely as we’ve been working together on this matter. To the best of my understanding, there is an issue with installing frontend-platform from source. This is not a problem of installing the right version.

To understand what is going on, run the following commands in, for instance, the frontend-app-profile repo (open-release/nutmeg.master):

$ npm install --no-save @edx/frontend-platform@1.15.6 # this the required version in Nutmeg
$ ls node_modules/@edx/frontend-platform/
analytics  config.js      constants.js      i18n  logging       package.json  utils.js
auth  index.js  initialize.js  LICENSE            node_modules  pubSub.js     react          testing

The installed package contains all the necessary files.

Now, install from the GitHub source repo:

$ npm install --no-save @edx/frontend-platform@git+
$ ls node_modules/@edx/frontend-platform/
docs  jsdoc.json  LICENSE  node_modules  openedx.yaml  package.json  service-interface.png  src

Notice how in the latter example the package source files are all contained in the src folder. This causes npm run build to fail further down the road.

This leads me to conclude that there is a problem in how frontend-platform is packaged.

The fact that we cannot install frontend-platform from GitHub means that it’s extremely difficult to install a forked version of frontend-platform – which we need in some cases, such as installing an extra language/locale, which @Dimitris_Angelakis is trying to do.

How are frontend-platform developers installing their local forks in the MFE environments?


This is in the README:

If you look at the build process it becomes a little clearer why these acrobatics are necessary, and why npm-installing directly from github might fail.

So… Yes, this makes customizing frontend-platform harder. It’s why I offered forking both the MFE and frontend-platform as a potential way out. At least it would help tracking the problem down.

I have a lot on my plate this week, but as soon as I get some time I can help look into a fool-proof, Tutor-flavored way of doing this so that we can put it in the README. (If anybody else wants to pitch in earlier, please do. :slight_smile:


Thanks for this detailed answer Adolfo, I appreciate it. With your help I’m sure we’ll be able to move forward.

Indeed the build process explains why we can’t install from GitHub, but I still don’t understand why the build process needs to be so complex. Having to manually cp and rm stuff around does not feel “right”. Of course this is a question that is less of an emergency.

1 Like

Agreed. I’m going to try and see if there’s a better way to do it.


Adolfo and Regis thank you both so much for the help on the matter!

I should probably mention that I’m pretty new to node (and react) and I’m struggling a bit to understand how the whole procedure works (especially in combination with the tutor way of implementing things) and most of the time I’m not sure I know what I’m doing, I just try to follow the existing README help if available.

I tried lots of things the last few days after your suggestion but they don’t seem to work or I do something wrong.
I actually used “nutmeg.2” tag code of "frontend-app-learning" and tag v1.15.6 of "frontend-platform" (I saw in frontend-app-learning'spackage.json’ file that’s the version of "frontend-platform" used, like Regis mentioned already) without changing their code (just to test if it will work), and I tried to incorporate them to my production (tutor local) platform but I am still receiving some errors. I even disabled the other three MFEs so they won’t “complain” about the changes, using something like:

tutor config save --set MFE_ACCOUNT_MFE_APP=null

but still no luck (I’m not sure though if disabling them it also blocks them from being build in there)…

I also noticed that the other MFEs, instead of v1.15.6 of "frontend-platform" they use v1.15.1 which complicates things a bit more since it seems I cannot use a different version for each MFE using this method…

This seems to be the solution to the different version of "frontend-platform" in each of the MFEs, but when I tried it with frontend-app-learning again it failed…

If i understand well this is for the development procedure (as it is titled in the README), right? Still I also hit the wall when I tried it but I didn’t insist on this, as my main problem is with pushing my changes in "frontend-platform" in production, and not so much the development part.

Still I really appreciate all those suggestions and help and I will keep trying in case I missed something due to my limited experience on the matter!

This would be a huge help for us, especially if you manage to describe, not only the development part but also the “Tutor-flavored way” of applying any changes on frontend-platform (or other components) to a "tutor local" production implementation of the platform.

@arbrandes & @regis Thank you for all the help!


Dear all,

I hope it’s fine for you for me to jump in here. I’m trying to achieve exactly the same goal as Dimitris, just for the German language. I’m also running tutor locally and trying to add the German translation (which is already available on Transifex) but not one of the already supported languages.

Same as Dimitris I noticed that only very few changes are needed to add support for the German language in general, but its very hard and not documented yet how to incorporate the changes into the Tutor environment.

If you could find any time to somehow document that fool-proof / “tutor flavoured” way, that would be very much appreciated also from our side. I’m also happy to help, although I’m not sure I can be of much help except for testing. If you only write down the steps needed in short bullet points, I’m happy to support by making a readable part of the documentation out of that.

Thanks for your help!


I’m having the same problem while trying to add an unsupported language in tutor MFE, I hope that there will be an easy way to do it.

I’m experiencing the same issue for the Turkish language. I tried to run also the forks of MFEs and Frontend Platform but the issue "Module not found: Error: Can't resolve '@edx/frontend-platform/..." is still there.

However, I hope this helps a bit, while trying different ways to resolve the adding extra translations I figured out that Frontend Account App somehow accepts extra translations.

I only did the following changes to the fork of Frontend Account App:

// add a new language
    code: 'tr-tr',
    name: 'Türkçe',
    released: true,
// add these changes
import trMessages from './messages/tr-tr.json';

const messages = {
  'tr-tr': trMessages,

And finally add translation file downloaded from Transifex to the src/i18n/messages/tr-tr.json path and change MFE Dockerfile to fetch your forked Git repository.

Rebuild the MFE images tutor images build mfe and tutor local start -d. You can change your language to this extra language which was not included in Frontend Platform. Honestly, no idea why this works with Account app.


Dear all,

I think I finally managed to find a solution that is also acceptable from tutor perspective. I’ll give a complete rundown here, so if someone else is facing the same issue, you should be able to follow the guide.

** Note that all changes described here must be repeated for each new release!** For the sake of an example, we’ll be modifying the most recent olive.2 release.

Background information

Some very high level information. MFEs are essentially standalone and independent ReactJS applications which communicate using the OpenEDX API with the main application stack. They all leverage common modules (like frontend-platform for example), but those are just regular npm dependencies.

When starting a Tutor environment, the tutor-mfe plugin is responsible for managing the MFEs. On a very high level, without going too much into detail, the plugin builds a Dockerfile based on a template and the plugin configuration, and this Dockerfile is then used to build the mfe container.

There is one single container (mfe) which hosts all MFEs. When the container is built, the Dockerfile contains various steps for each MFE, like clone the source code, apply some i18n changes, do npm install and build. That means the container essentially just serves static assets (the compiled react application).

Now the general idea to add additional languages is to create a fork of each MFE repository we’re interested in and make sure those repos are used to build the new MFE container.

This next section just describes the changes you need to do, the second section focusses on how to do them.

Required Changes

In general, there’s two changes that need to be done:

  • Custom translation needs to be added to each MFE you’re interested in
  • Language need to be added to the dropdown in the account MFE so users can actually choose

To add your language to the dropdown on the account page, you’ll need to modify src/account-settings/site-language/constants.js in frontend-app-account:

index 6854958..efea6e0 100644
--- a/src/account-settings/site-language/constants.js
+++ b/src/account-settings/site-language/constants.js
@@ -14,6 +14,11 @@ const siteLanguageList = [
     name: 'Català',
     released: false,
+  {
+    code: 'de-de',
+    name: 'Deutsch',
+    released: true,
+  },
     code: 'es-419',
     name: 'Español (Latinoamérica)',

Second, to add your language to the MFE, the following steps need to be done (its the same for each MFE, so you need to apply these changes to each MFE):

Update src/i18n/index.js to include your language, in this example, German has been added:

index 8a01428..b762993 100644
--- a/src/i18n/index.js
+++ b/src/i18n/index.js
@@ -1,6 +1,7 @@
 import arMessages from './messages/ar.json';
 import caMessages from './messages/ca.json';
 // no need to import en messages-- they are in the defaultMessage field
+import dedeMessages from './messages/de_DE.json';
 import es419Messages from './messages/es_419.json';
 import frMessages from './messages/fr.json';
 import zhcnMessages from './messages/zh_CN.json';
@@ -15,6 +16,7 @@ import ukMessages from './messages/uk.json';
 const messages = {
   ar: arMessages,
+  'de-de': deMessages,
   'es-419': es419Messages,
   fr: frMessages,
   'zh-cn': zhcnMessages,

Next, fetch your language file from Transifex (if it exists), you need a JSON file. Some common transifex repositories:

Once you’ve located the transifex project you’re interested in, click on your language and click on Download for use. This should give you a JSON file. Rename this file according to the import in index.js and place it in i18n/messages/ (in our example, this would be i18n/messages/de_DE.json).

Apply changes

To apply these changes, perform the following steps for each MFE you want to modify

  • Fork the MFE (make sure not only to copy the master branch, you need everything)
  • Clone it to a local directory
  • Go to the official OpenEDX Repository for the MFE you’re modifying and find the commit hash associated to your release (8dbf20b in this example).

  • In your local clone, create a new branch off this commit: git branch your_org_olive.2 8dbf20b && git checkout your_org_olive.2
  • Make the changes described above
  • Next, we’ll commit all changes and move the release tag to the new version you’ve just created. Alternatively, you can use a custom tag and specify the version attribute for the MFE config later.
# Add all modified files
$ git add -A

# Commit all changes
$ git commit -m "your org specific olive.2 release"

# Delete existing release tag
$ git tag --delete open-release/olive.2

# Create a new release tag pointing to your new commit
$ git tag open-release/olive.2

# Alternatively, omit the previous two steps and simply create a new tag:
$ git tag your-org/olive.2

# Assumes origin is your remote
$ git push origin
$ git push origin --tags -f # Force (-f) is only needed if you changed the original release tag, as the tag still exists in the remote repository

Make Tutor use your new forks

The final step is to tell Tutor to use your new forks. To do this, modify your config.yml ( $(tutor config printroot)/config.yml) and add the following for each MFE:

  name: <mfe_name>
  port: <mfe_port>

# Example
  name: authn
  port: 1999

# Example with version
# Optionally, if you don't use the official release tag for your changes, you can do:
  name: authn
  port: 1999
  version: your-org/olive.2

Note that you can find the defaults (MFEs, ports and their Repositories) here. Note that you need to prefix the configuration variable names by the plugin name (MFE in this case).

Warning: While it might be tempting to simply change them in the Dockerfile ($(tutor config printroot)/env/plugins/mfe/build/mfe/Dockerfile), this is a bad idea as those URLs would be overwritten by the next tutor config save.

Last but not least, rebuild the MFE image and restart the container, picking up the new image:

$ tutor images build mfe
$ tutor local dc up -d mfe

I hope this helps someone.


@onurcan you may want to consider changing your modified Dockerfile to the method I propose to avoid the URLs being overwritten.

Thank you @onurcan and @Wasabi for your suggestions!

Due to lots of other issues, too much work and lack of time I haven’t managed to check your suggestions yet to see if they will work on my case, but I am starting with it now and I hope to have some results or possible input on the matter.
Moreover, I will be attending the Open Edx conference next week and I hope to talk in person with @arbrandes about this, so, hopefully, I might have an update soon.

I just want to add that the whole MFE transition creates even more problems for our Open Edx implementation apart from the language issue, as we have made some changes to the previous mako templates that are of course no longer used in the MFEs, so, it’s imperative for us to be able to edit some of the MFEs and then embed them back to the platform, so, a solution to this would be much more helpful for us (and possibly others) apart from the mere implementation of a new language.

1 Like

After some time and after several trial-and-error attempts I had finally managed to make the MFEs to work with my custom changes for supporting the Greek language (and the corresponding translation files) thanks to @Wasabi (although I did everything similarly, the only step I had missed was to checkout the appropriate tag before applying the changes to my Open Edx local implementaion), and I managed to do it just a couple of days before the Open Edx conference in MIT where I have also met with many really amazing and helpful people!

I have created my own step-by-step guide, quite similar to that of @Wasabi and I can post it here if anyone would like to see it! I might post it in one of the following comments here.

I still have some problems though with certain parts of the platform, and more specifically, my latest encounter of such a problem is with the ‘frontend-component-header’ (and footer) component, which needs a different approach than the MFEs, and that’s because it needs to be installed as a library inside node-modules/@edx of each of the MFEs that use it, and although according to the documentation here:
the implementation seems quite straightforward with the use of a patch ‘mfe-dockerfile-post-npm-install’ inside a tutor plugin, it never works and produces dependency errors…

My guess is that (similarly to the ‘frontend-platform’ component that it’s actually being used inside the ‘frontend-component-header’ component) because this particular component is used by several MFEs (like the Learning and the Account MFEs), and each of them uses a different version of the ‘frontend-component-header’, there is no way using this tutor patch to tell each MFE to use a different version of the component…

For example, the olive.3 tag of the ‘frontend-app-learning’ MFE has as a dependency the version ‘3.1.0’ of ‘frontend-component-header’, while the olive.3 tag of the ‘frontend-app-account’ MFE has as a dependency the version ‘3.2.1’ of ‘frontend-component-header’, and the other MFEs also use different versions of the component…

Does anyone know if there is an easy way to overcome this problem?

Also, I have another question: if I want to use my specific github tag or branch of my ‘frontend-component-header’ fork, is it correct if I call it like following inside my tutor plugin?:

RUN npm install '@edx/frontend-component-header@git+'

where ‘mybranchortagname’ is the name of the branch or tag with my custom changes…

I tried it like this and it doesn’t work because of the dependency errors, but I’m not sure it if tries to get the code from my branch or tag, or it gets the master branch… Either way, I still wouldn’t know which version to use as each MFE uses a different version of the component like I explained before…

@arbrandes @regis

1 Like

Hi @Dimitris_Angelakis!

I, for one, would love to see your guide. Mind posting it here?

In some cases it’s possible to check which MFE is being used in the patch itself (we did this here for the Library Authoring MFE), but I don’t think there’s a clean way to do the same with the Dockerfile.

With that in mind, I just submitted a PR to tutor-mfe that would allow you to specify a post-npm-install patch per mfe, in addition to the common one. For instance, mfe-dockerfile-post-npm-install-learning, or mfe-dockerfile-post-npm-install-ora-grading. Let’s see what the reviewers say.

The syntax looks correct, yes.

1 Like

That PR just merged!

1 Like

@arbrandes that’s amazing news, thank you so much!!!
Will it work on Olive.3 or only in the latest Palm release?

When we meet again drinks and food are on me (Especially if you visit Crete, you and the other guys are most welcome)!!!

On the next post I will add my guide for adding a non supported language to the MFEs, if you have time to check it please let me know if there are any mistakes or anything not in accordance to the proper procedures!

Only on Palm, I’m afraid, sorry!

I’ll take you up on that! I’m running out of excuses not to visit Greece! :smiley:

Adding a non supported language to Open Edx MFEs
(This guide could possibly be used for any custom changes on the MFEs)

@Wasabi and @onurcan helped quite a lot and their guides here are quite explanatory but I decided to add a bit more detail in the steps needed, for guys like me that are just starting dealing with the MFEs and are quite lost (like I was). I really hope this guide will be helpful!!!

To change the language in which a MFE will be displayed, if this particular language is not in the current limited list of supported languages, (up to the current Open Edx release, olive.3), we must follow the steps below:

PART 1: Forking an MFE

First we have to go on github and fork each one of the MFEs we want to change, moreover, I’d suggest to fork and edit first the frontend-app-account (the Account) MFE in order to add our new language in the dropdown selection of the languages list under “Site Preferences>Site Language” options.

IMPORTANT: After forking an MFE we should clone it locally on our computer and then checkout the respective tag of the Open Edx Release we wish to make the change on, in our case this tag should be “open-release/olive.3” as this is the latest stable release at the time of this guide.
After that, my personal preference is to create a branch from this tag.
The branch name on this guide is named as “dagg” just to make things simpler, but you could use something like “dagg.olive.3” so as to have a clear view of which release it is based on!

Forking is done in github and the forked repo is placed in your github area, so, In detail, the steps are the following (after forking an MFE –e.g. the ‘frontend-app-learning’ MFE– from its original github repo to our own and cloning it to our local computer):

$ git clone
$ cd frontend-app-learning

For the ACCOUNT MFE we do the following:

$ git clone
$ cd frontend-app-account

And similarly for all MFEs.

Then we checkout the TAG we want to make the changes on:

$ git checkout open-release/olive.3

After that we create a branch based on this tag and we checkout on it:

$ git branch dagg
$ git checkout dagg

or we just run:

$ git checkout -b dagg

Now we can work on this branch directly.

PART 2: Mounting an MFE to our tutor dev Open Edx for being able to see live changes.

Using “tutor dev” we can work on this branch and see every change we make in the code on the fly by using the “--mount” option. This will mount the forked MFE on the dev version of Open Edx we are currently running on our computer using “tutor dev”.

Firstly though, and while we are inside the cloned MFE’s folder, we must run the following:

$ npm install

We have to do this in order for the “node-modules” folder to be created so our forked and mounted MFE can run properly with our tutor dev Open Edx implementation.
If the “npm install” produces any errors there is a chance this might help:

$ npm cache clear --force

Now, to mount the MFE to our dev platform (our tutor dev must be already up and running) we run the following (from inside our forked and locally cloned MFE folder):

$ tutor dev start learning --mount=.

Or for the ACCOUNT MFE (from inside the MFE’s forked and locally cloned folder):

$ tutor dev start account --mount=.

And so on, for each MFE…

According to the above command, the “learning” (or “account” etc) MFE will be mounted to our tutor dev Open Edx installation and every time we make an edit to its code it will show directly on the Open Edx page in our browser.

If we feel quite optimistic, we can avoid the above steps for mounting the MFE locally to our “tutor dev …” and directly make the changes in the code, but even the easiest and smallest change could have some errors which we won’t be able to see until we deploy the changes to production, so, this is not suggested!

PART 3: Changes to MFEs for supporting a new language

Once we have mounted the MFE to tutor dev, we can edit the MFE’s code using our preferred editor.

First we need to change the ACCOUNT MFE for adding the new language to the “site language” dropdown so the user will be able to select it.

To do that we need to edit this file:


And add out language (in my case the Greek language) like so:

In the “siteLanguageList” array we add this:

   code: 'el',
   name: 'Ελληνικά',
   released: true,

So it will become something like this:

const siteLanguageList = [
   code: 'el',
   name: 'Ελληνικά',
   released: true,
   code: 'en',
   name: 'English',
   released: true,


Be very careful with the “code” part because if it’s not the correct code for the specified language it will not work!

After that, we need to add the file with the added language’s translations to our MFE so the translations will be applied on the web pages created by the MFE.

We can find this file in Transifex, under the Edx Platform translations, with a name that corresponds to this particular MFE for the particular translation language.

The translation file for the Greek language on Trasifex for the Account MFE will have the following name: “for_use_edx-platform_frontend-app-account_el.json
(Transifex allows to download several different versions of the resource files, for example, one for translation and one for use on the platform etc, we choose the one for use on the platform)

Of course if we want we can create our own messages file but this needs to be done according to the translation guidelines. It’s much easier and faster to download it from Transifex after making the needed translations there so they’ll be available for all users.

After we download the file, we rename it to our language’s code, so this particular file will be renamed to: “el.json” since “el” is the code for the Greek language.

We must copy this file in the following folder inside our MFE, as follows:


We then need to edit the following file:


To make it “aware” of the new translations file we added and the new supported language. It’s a very simple file, and we just need to add two things there:

At the first part of the file we add the following line in between the other similar lines:

import elMessages from './messages/el.json';

And at the second part (inside the “messages” object) we similarly add the following:

el: elMessages,

So the whole file will become something like this:

import arMessages from './messages/ar.json';
import elMessages from './messages/el.json';  //This is the first line we added 
import caMessages from './messages/ca.json';
// no need to import en messages-- they are in the defaultMessage field
import es419Messages from './messages/es_419.json';
import frMessages from './messages/fr.json';
import zhcnMessages from './messages/zh_CN.json';
import heMessages from './messages/he.json';
import idMessages from './messages/id.json';
import kokrMessages from './messages/ko_kr.json';
import plMessages from './messages/pl.json';
import ptbrMessages from './messages/pt_br.json';
import ruMessages from './messages/ru.json';
import thMessages from './messages/th.json';
import ukMessages from './messages/uk.json';

const messages = {
 ar: arMessages,
 el: elMessages,  //This is the second line we added
 'es-419': es419Messages,
 fr: frMessages,
 'zh-cn': zhcnMessages,
 ca: caMessages,
 he: heMessages,
 id: idMessages,
 'ko-kr': kokrMessages,
 pl: plMessages,
 'pt-br': ptbrMessages,
 ru: ruMessages,
 th: thMessages,
 uk: ukMessages,
export default messages;

That’s all !!!

After we save these changes we should be able to see (on the fly, if we mounted the MFE to our tutor dev) the new language (the Greek language in our example) in the “site languages” dropdown, and the whole Account MFE and its pages should be translated to the Greek language (since we have selected the Greek language as the default language of our platform, or, we choose Greek from the dropdown), according to the translations inside the “el.json” file we put inside the corresponding folder in the MFE as shown above.

PART 4: Deploying the changes to tutor local (Open edX Production Platform)

Now that we have added the new language and made sure it works properly, we need to deploy these changes to our production platform.

First we need to commit our local changes and then push them to our forked repo on github (we use “git add”, “git commit” and “git push” respectively).

After all changes are pushed to our github repo, (on the “dagg” branch in this example’s case, but as I suggested, your branch should preferably be named in accordance to the Open edX Release Tag it represents), we need to make our production platform aware of our changed MFE’s new repo and make it pull it from there instead of the original repo.

Thankfully, and thanks to the amazing guys at Tutor, this is quite easy!

In our production machine (tutor local), we first want to see which repo is used by our production platform for the ACCOUNT MFE, and some other configuration info it needs to run properly (like the local port it uses, etc).

To do that we just run:

$ tutor config printvalue MFE_ACCOUNT_MFE_APP

Most likely the result will be the following:

{'name': 'account', 'repository': '', 'port': 1997}

This looks like a python dictionary or a JSON object, and there we can see the name of the MFE (‘account’), the remote repo from which it is pulled to be built locally on our platform during it’s setup (‘’) and the local port on which this particular MFE is supposed to run (‘1997’).

We can change these details and use our own repo address, the same port and name of course and we can also add our branch name to make sure that our platform will bring the changed code in our branch and not the original code from the master branch.
To do this we run the following:

$ tutor config save --set "MFE_ACCOUNT_MFE_APP={'name': 'account', 'port': 1997, 'repository': '', 'version': 'dagg'}"

Using “tutor config save --set ...” we can change the value of several of tutor’s configuration variables, so here we have set the “MFE_ACCOUNT_MFE_APP” to get the same name as and port before (else it wouldn’t work), and use our own repo with the code containing the additional language, and we also use the key name “version” to denote our branch containing the changed code from our repo.

Since we do this with “tutor config save”, we can find these changes inside the tutor’s configuration file in the form of yaml, like so:

  name: account
  port: 1997
  version: dagg

We could have put these changes directly in this file, but I find the method above much easier. We can make changes directly to the config file though and then run

$ tutor config save

in order for these changes to take effect.

To edit (or view) the tutor config file we run:

$ vim "$(tutor config printroot)/config.yml"

Now, in order for these changes to be applied to our production platform (tutor local) we need to run:

$ tutor images build mfe

And although the official documentation doesn’t mention it (at least not on my knowledge), I found out that in order for the changes to take effect we also need to run:

$ tutor local launch

(Maybe this makes the “tutor images build mfe” not necessary but I haven’t tried it yet)

And that’s all! After these last steps the new language (or any other changes we have made on the MFEs’ code) should be applied to the Account MFE !
Adding the new language to the other MFEs

In order to make the language available to the other MFEs as well we need to follow all the previous steps for each one of the MFEs, apart from the first step (STEP 1) that only applies to the Account MFE (the step where we add the new language to the dropdown)!

Everything else is the same!

If we need to make changes to more than one MFEs at the same time, we can follow all the above steps and only run

$ tutor images build mfe


$ tutor local launch

just once at the end for applying the changes for all the MFEs at once (since these steps take quite some time, sometimes).


1 Like

No problem! I will start experimenting with Palm soon, and we’ll possibly be able to eventually move there from Lilac (yes, we’re that far back)!!!

The offer is always open, any time you like, sooner better than later! Tell it to @regis as well, he’s also promised he’ll come here, it will be a nice reunion for all :smiley:
I have posted my guide, let me know if I need to correct anything :slight_smile:

1 Like