Customise MFEs Branding

I’ve looked into customising the branding for the MFEs and right now there are two paths:

  • Override Logo URLs variables in the environment.
  • Override @edx/brand package.

Logo URLs

At the moment, we have to override the values using patches (mfe-env-production, mfe-env-development) and to override LOGO_URL, we have to add a variable LOGO_URL using the patch.

Would it be more convenient to have a variable that can be set in the config file? The definition of the variable in the plugin would become

LOGO_URL='{% if MFE_LOGO_URL is defined %}{{ MFE_LOGO_URL }}{% else %}{{ "https" if ENABLE_HTTPS else "http" }}://{{ LMS_HOST }}/static/images/logo.png{% endif %}'

And adding to config.yml


Let me know what you think, I’ve created a draft PR to show the changes.

Overriding @edx/brand package

As described in OEP-48, the @edx/brand package override can be done from github using a fork of brand-openedx.

npm install @edx/brand@git+

I don’t think there is anyway right now in tutor to apply the branding package to all MFEs. I propose we add the following patch to the dockerfile (see PR).

{{ patch("mfe-dockerfile-npm-overrides") }}
RUN npm install --verbose --registry=$NPM_REGISTRY

With this patch, the following plugin overrides the brand package:

name: mfe-branding
version: 0.1.0
  mfe-dockerfile-npm-overrides: |
    RUN npm install @edx/brand@git+

Hey Sofiane,

Sorry for the late reply :-/ Here’s my opinion on these two items.

Logo URLs

It makes total sense that operators should be able to easily override MFE branding urls. However, I’d rather avoid introducing many additional plugin settings. Instead, our approach so far has always been to:

  1. Provide good defaults.
  2. Make it possible to override these defaults with the help of plugins.

In the case of MFE branding urls, I propose the following:

  1. Define good default branding urls that point to the LMS favicon, logo, etc. both in development and production.
  2. Describe in the tutor-mfe README how to make use of the “mfe-env-production” and “mfe-env-development” patches to override these values.

Would that make sense to you?

Overriding @edx/brand package

Your proposal makes total sense (again). I would only propose a different patch name: “mfe-dockerfile-pre-npm-install”. Also, we should take the opportunity to add “mfe-dockerfile-post-npm-install” to install requirements after the first npm install command is run.

I see that you already opened a PR: Enable npm packages override for all MFEs by BbrSofiane · Pull Request #17 · overhangio/tutor-mfe · GitHub If you agree with the name change (and the extra patch) would you like to amend it?

Logo URL

Yes, it makes sense. It did feel like a lot of variables. Also documenting the process will clarify it.

I’ll modify my PR to include these two points.

Overriding @edx/brand package

Happy to change the name but in that case, would it also make sense to add documentation to the Readme? I set the name as it is so that the intent is obvious. Though I understand it’s not “just” for overrides.

For the Readme, I also want to add screenshots of the resulting customised MFE. Can you create a fork of brand-openedx (brand-overhangio?)?

I’m not sure what this new repo is for? Do we want to provide a good usable theme out of the box that is different from brand-openedx? I think that’s a great idea, in the same vein as providing the indigo theme. But will it be very different from the brand-openedx package? Shouldn’t we make changes to the upstream theme instead?

Maybe create a brand-indigo package, matching the indigo theme?

Hi @regis and @BbrSofiane! I followed this thread and I was able to install custom branding and components to MFEs with a patch to mfe-dockerfile-post-npm-install. Thanks for making that possible!
However, I am wondering what you would think about adding configuration values for the same?
For example, adding something like follows to the mfe Dockerfile:

{% for key, value in MFE_NPM_CONFIG_EXTRA.items() %}
  RUN npm config set '{{ key }}' '{{ value }}'
{% endfor %}
{% for item in MFE_NPM_OVERRIDES %}
  RUN npm install '{{ item }}'
{% endfor %}

So, one could use MFE_NPM_CONFIG_EXTRA to define a private registry and token for custom components and MFE_NPM_OVERRIDES to install said components and branding.
A config.yml example:

  '//<project_id>/packages/npm/:_authToken': <token>
- '@edx/brand@git+https://<brand_repo>'
- '@edx/frontend-component-footer@npm:@foo/<custom_footer_component>@<version>'

I’d say the gain would be one less yaml plugin (which at least in our case would have to be additionally configurable) and with added docs this could be quite user friendly. Of course, I might be missing something that would make this a bad idea :slight_smile:
Would a PR for such a change be welcomed or should we stick to using a yaml plugin?


Hi @mrtmm,

So right now to customise the branding you have a plugin like this

name: mfe-branding
version: 0.1.0
  mfe-dockerfile-post-npm-install: |
    RUN npm config set '//<project_id>/packages/npm/:_authToken' <token>
    RUN npm config set @foo:registry<project_id>/packages/npm/
    RUN npm install @edx/brand@git+https://<brand_repo>'
    RUN npm instal @edx/frontend-component-footer@npm:@foo/<custom_footer_component>@<version>

and instead you’re suggesting we add config parameters to replace the above plugin by

  '//<project_id>/packages/npm/:_authToken': <token>
- '@edx/brand@git+https://<brand_repo>'
- '@edx/frontend-component-footer@npm:@foo/<custom_footer_component>@<version>'

Is that correct?

Personally, I have 1 plugin that has all the patches specific to my instance so I don’t really view this as a problem. But I appreciate that depending on the scale of your deployment it might not be that simple so my opinion on this might be skewed :sweat_smile:.

I see that having configuration parameters like MFE_NPM_CONFIG_EXTRA and MFE_NPM_OVERRIDES makes the intent more explicit and gives users a clear path. I guess the downside is that it also narrows the scope of the customisation.

Ideally, we don’t end up creating specific configuration values for specific types of customisation but instead provide the entry points for users to do what they need.

Do you picture having both the parameters you suggest and the patch mfe-dockerfile-post-npm-install?

I’m leaning towards not adding those extra configuration settings but I think having a tutorial for “How to use components from a private registry” could be a good way to document the process.


Right, I guess that makes sense. Because tutor-mfe is a plugin itself I figured it could support such configurations that should be generally useful.

I wouldn’t want to take away any possibilities of customisation, so yes, I guess I’d keep both.

Fair enough :slight_smile:
I could write up some notes on that. Where should that go, in the README?

I agree with everything that @BbrSofiane said here. I would just like to add that you can point to a private registry when building your mfe image by defining the NPM_REGISTRY build argument: tutor-mfe/Dockerfile at 0ed49fe7c66be380236276642ad1f5778bf5eb11 · overhangio/tutor-mfe · GitHub
(I use it very often)

That would be awesome!

Yeah, I saw that option. How do you configure the access to such registry though? We should have that noted in the docs as well then.
My experience in this so far is limited to using gitlab’s private package registry, which requires a token. Here’s my PR: docs: Add notes on installing custom components by mrtmm · Pull Request #39 · overhangio/tutor-mfe · GitHub

Given that you opened that pull request I assume that you found the answer to your own question :slight_smile: Thanks again!

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.