Dynamically translating a PrimeNG menu using ngx-translate
How to translate a PrimeNG menu dynamically
Recently, for our awesome startup project, we’ve decided to move away from Angular Material and to switch to Tailwind + PrimeNG.
The reason for this move is the fact that our designer’s work feels too distant from Material Design and we’re not willing to swim against the flow. We feel like overriding all the Angular Material styles is not going to be easy and would be hacky (at best).
As part of this transition to PrimeNG, we had to rewrite our mat-menu usages to Prime NG’s “equivalent” menu component.
In this article, I’ll explain how we’ve managed to translate the PrimeNG menu dynamically.
The problem
The boon and bane of Prime’s menu system is that it is backed by a powerful menu model.
The nice thing about that model is that we can statically define the menu’s configuration, pass it as input to the p-menu and let it render everything for us.
What’s less nice is the fact that we have very limited control over how the menu items are rendered, as opposed to Angular Material’s mat-menu component, which uses content projection and thus lets us insert whatever we want into the menu easily.
This is problematic at least in the context of internationalization, because the labels that we pass to the menu aren’t dynamic. They’re set once and don’t get automatically updated. Bummer!
With mat-menu, we simply has to use ngx-translate’s translate pipe and it worked fine. With PrimeNG’s menu, we had resort to translateService.instant(...)
, which does a one-time translation that doesn’t get updated automatically.
Here’s what our menu looks like once converted to PrimeNG:
And the template:
The problem is that with this in place, the menu translations are interpolated only once at construction time (during ngOnInit), but those don’t get re-evaluated when the language is changed. Bummer!
The solution
After looking into it a bit, only two solutions stood out:
- Fork PrimeNG’s menu to bend it to our will and be able to use the translate pipe directly against the labels provided in the menu model
- Rebuild the menu model whenever the language changes so that it contains the correct translated text
For now, we’ve started with the second option. The first one would be better for other reasons, but also problematic because it would introduce technical debt.
So here’s our plan: subscribe to language changes events and rebuild the whole menu each time the language changes.
In our application, we store the current language in the NGRX store and our facade simply exposes a selector to let us watch for value changes, which makes this really easy, but the same can be achieved using the onTranslationChange
event emitter exposed by the TranslateService
service of ngx-translate:
With this, we get warned whenever the language changes. When that happens, we need to rebuild the menu. Note that the example code above doesn’t handle the subscription correctly; don’t forget it for your applications though or you’ll introduce a memory leak ;-)
In order to do this easily, we’ve simply moved the construction code of our menu model in a factory method:
Whenever the language change callback is invoked, we just have to call our buildUserProfileMenu method to get a new version of the menu with the correct translations.
Here’s an overview of the code:
Problem solved!
Conclusion
In this small article, I’ve described how we’ve handled the internationalization of our new PrimeNG menu.
I’m not really happy about how we had to do it, but this is the cleanest approach I could find.
That's it for today! ✨
About Sébastien
I am Sébastien Dubois. You can follow me on X 🐦 and on BlueSky 🦋.
I am an author, founder, and coach. I write books and articles about Knowledge Work, Personal Knowledge Management, Note-taking, Lifelong Learning, Personal Organization, and Zen Productivity. I also craft lovely digital products . You can learn more about my projects here.
If you want to follow my work, then become a member.
Ready to get to the next level?
To embark on your Knowledge Management journey, consider investing in resources that will equip you with the tools and strategies you need. Check out the Obsidian Starter Kit and the accompanying video course. It will give you a rock-solid starting point for your note-taking and Knowledge Management efforts.
If you want to take a more holistic approach, then the Knowledge Worker Kit is for you. It covers PKM, but expands into productivity, personal organization, project/task management, and more:
If you are in a hurry, then do not hesitate to book a coaching session with me: