[Dos and Don’ts #2] Translation in JavaScript

In an effort to increase the code quality of contributions to ERPNext and other frappe apps, I started to post some examples of code I found and how it could be done better. The previous post was on the advantages of frappe.db.get_value over frappe.db.sql. Today we’re looking at how to translate strings in JavaScript.

My code is of course not perfect. You’re welcome to comment suggestions on how it could be improved.


const empty_state_message = __(`No featured items yet. Got to your
    <a href="#marketplace/published-items">
    Published Items</a>
    and feature upto 8 items that you want to highlight to your customers.`)
const views_message = __(`${this.item.view_count} Views`);
  • Translators should’t need to know HTML and shouldn’t be able to mess it up accidentally.
  • The translation setup doesn’t support template strings; views_message would not get translated. For the same reason you shouldn’t do this in python:
views_message = _('{} Views'.format(view_count))

Source: frappe/erpnext


const empty_state_message = __('No featured items yet. Got to your {0} and feature up to eight items that you want to highlight to your customers.',
    [`<a href="#marketplace/published-items">${__("Published Items")}</a>`])
const views_message = __('{0} Views', [this.item.view_count]);

The translation function takes a second parameter, a list of variables that will be substituted into the translated string at runtime. We can pull out the HTML and the view count.

Strings within the HTML, “Published Items” in this case, also need to get translated. This can be achieved by calling the translation function from within a template string (not the other way round).

In python, the solution is to format the translated string, not the source string:

views_message = _('{} Views').format(view_count)

That’s it, have a nice day!


I see many variables, url, fieldnames, and icon names are included in the translation tags.
And because Frappe and ERPNext are translated by sending script to Google, most of them also got translated word by word.
This causes problems because when changing language the string/variable/fieldname/etc can’t be found.