I successfully edit the footer and header, but I can’t add translations. I thought the method would be the same as in the edx-platform, but it seems it’s done differently.
Did I understand correctly that I need to add an id
to the text?
PLUGIN_SLOTS.add_items([
(
"all",
"footer_slot",
`
{
op: PLUGIN_OPERATIONS.Hide,
widgetId: 'default_contents',
}`
),
(
"all",
"footer_slot",
`
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'custom_footer',
type: DIRECT_PLUGIN,
RenderWidget: () => (
<footer style={{
backgroundColor: '#002554',
color: '#ffffff',
textAlign: 'center',
padding: '20px 0',
fontFamily: 'Arial, sans-serif'
}}>
<h1 style={{ margin: 0, fontSize: '24px' }}>
<FormattedMessage id="footer.title" defaultMessage="Welcome to our platform" />
</h1>
<p style={{ margin: '5px 0 0', fontSize: '14px' }}>
© 2025 Все права защищены.
</p>
</footer>
),
},
}`
)
]);
Then, add the translation message to the appropriate repository:
transifex_input.json
and provide translations here:
messages/
why it isnt working
@brian.smith - two areas of your expertise! We should also document the best way to do this.
I believe this falls under the “custom translations” use case @omar described in his lightning talk last year.
This process is also described on the Tutor documentation site:
Hopefully this helps! Please let me know if you have any more questions!
"I found a solution—surprisingly, with the help of ChatGPT . It gave me code that actually worked.
PLUGIN_SLOTS.add_items([
(
"all",
"footer_slot",
"""
{
op: PLUGIN_OPERATIONS.Hide,
widgetId: 'default_contents'
}"""
),
(
"all",
"footer_slot",
"""
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'custom_footer',
type: DIRECT_PLUGIN,
RenderWidget: () => {
const { FormattedMessage } = require('@edx/frontend-platform/i18n');
return (
<footer style={{
backgroundColor: '#002554',
color: '#ffffff',
textAlign: 'center',
padding: '20px 0',
fontFamily: 'Arial, sans-serif'
}}>
<div style={{ marginBottom: '10px' }}>
<a href="/about" style={{ color: '#fff', margin: '0 10px' }}>
<FormattedMessage id="footer.edxLinks.about" defaultMessage="About" />
</a>
<a href="/privacy" style={{ color: '#fff', margin: '0 10px' }}>
<FormattedMessage id="footer.legalLinks.privacyPolicy" defaultMessage="Privacy Policy" />
</a>
</div>
<div style={{ fontSize: '12px', marginTop: '10px' }}>
<FormattedMessage id="footer.logo.altText" defaultMessage="Powered by Open edX" />
</div>
</footer>
);
}
}
}"""
)
]);
@brian.smith @abylaikhan.suev.02 - should we add or consolidate docs anywhere? Should we link to the lightning talk slides or video somewhere?
I’m glad you found something that works for you! I do want to point out the limitations of the code ChatGPT generated.
You originally asked about adding translations, which isn’t quite what is happening here.
Your original code was using the id footer.title
, which does not exist in frontend-component-footer
.
The generated code uses keys that do exist in frontend-component-footer
, so the translations that already exist continue to work, but this is not a solution that would work for adding translations.
That’s fine, you just need to add the appropriate translation to openedx-translation. Next, add the translation using the tutor images build mfe --no-cache command
Example:
1.
I’ve given this text id=footer.training.title
2. Then i add to openedx-translation/translation/frontend-component-footer/src/i18n/transifex_input.json
3. and finally I am adding a translation openedx-translation/translation/frontend-component-footer/src/i18n//messages/ru.json
4. tutor images build mfe --no-cache.
I think you need to add to the documentation that it’s necessary to include const { FormattedMessage } = require('@edx/frontend-platform/i18n');
in the plugin slot so that translations can be used.
And not only for translations, but also if icons need to be added, then add them
const React = require(“react”);
const { useContext, useState, useRef, useEffect } = React;
const { AppContext } = require(“@edx/frontend-platform/react”);
const { FontAwesomeIcon } = require(“@fortawesome/react-fontawesome”);
const { faUser } = require(“@fortawesome/free-solid-svg-icons”);