Dynamically translating a PrimeNG menu using ngx-translate

How to translate a PrimeNG menu dynamically

ngx-translate logo: Angular shield with a robotic face, used for i18n in PrimeNG menus

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! ✨


Go Further

How to create a custom Angular Webpack configuration
Understand how you can customize the Webpack configuration of your Angular applications
Angular 13 in Depth
Everything you need to know about Angular 13
Angular 12 in Depth
Everything you need to know about Angular 12

Want to go deeper?

Knowii Community - Master Knowledge Management + AI | From €4.99/month
Join 400+ members mastering Knowledge Management AND AI. Community + Courses + Tools integrated. €500+ value in Knowledge Master tier.

About Sébastien

I'm Sébastien Dubois, and I'm on a mission to help knowledge workers escape information overload. After 20+ years in IT and seeing too many brilliant minds drowning in digital chaos, I've decided to help people build systems that actually work. Through the Knowii Community, my courses, products & services and my Website/Newsletter, I share practical and battle-tested systems.

I write about Knowledge Work, Personal Knowledge Management, Note-taking, Lifelong Learning, Personal Organization, Productivity, and more. I also craft lovely digital products and tools.

If you want to follow my work, then become a member and join our community.

Ready to get to the next level?

Want to level up as a developer?

Found this valuable? Share it with someone who needs it.

Join 6,000+ readers. Get practical systems for knowledge & AI. Free.

Subscribe ✨

Free: Knowledge System Checklist

A clear roadmap to building your own knowledge system. Subscribe and get it straight to your inbox.

6,000+ readers. No spam. Unsubscribe anytime.