DEV Community

Cover image for How to translate a PWA app manifest
Kevin Basset
Kevin Basset

Posted on

How to translate a PWA app manifest

As of October 2022, there's no native way to localize properties of the web app manifest in multiple languages. Although there's been an open request for that since 2018, so far there's no definitive way to achieve this with a conventional static app manifest file.

In this article, I'll tell you about the three methods you can use to localize your PWA manifest, including the one I'm using to provide the localization functionality at Progressier.

Method 1: Static app manifests

If your app has properly scoped language versions hosted at their own URLs, you can simply create different app manifest for each of them.

Say your English app is at https://example.com/en/ and your French app is at https://example.com/fr/, then you can simply host the manifests at https://example.com/en/manifest.json and https://example.com/fr/manifest.json respectively.

This would work similarly if your English app is at example.com and your French app is at fr.example.com. You'd then host your manifests at example.com/manifest.json and fr.example.com/manifest.json

The first drawback of that method is that browsers consider each entity unique PWAs. So when a user installs the English version from example.com, they'll be prompted to install the French version when they access fr.example.com.

Not great.

Counterintuitively, in this specific case, having overlapping scopes would actually be the better option.

The second issue is that this method violates Don't Repeat Yourself principles. In the long run, this is harder to manage and tends to lead to errors. It also doesn't scale well — if tomorrow your app is available in 20 different languages, do you really want to modify 20 different manifest files whenever you update your logo?

Method 2: Server-side dynamic app manifest generation

In general, one PWA = one app manifest. A PWA typically isn't updatable after installation if the URL of the manifest changes. So you should strive to keep the URL of the manifest unchanged as much as possible — even if it might be possible to do things a bit differently now thanks to the new id property.

A more scalable approach is to generate the manifest server-side instead of simply storing it as a static asset. This is the method I use at Progressier.

Browsers automatically add a Accept-Language header to every fetch request. The Accept-Language is determined based on the user's preferred language set in their browser. If you're using Chrome, you can define your own list of preferred languages at chrome://settings/languages.

Here is how to translate your manifest server-side:

  1. Link to the manifest as usual in your client-side code. Simply add <link rel="manifest" href="https://example.com/manifest.json"> between the <head> and </head> tags in your HTML document.
  2. In your server-side code, add a GET route for /manifest.json
  3. Get the Accept-Language header
  4. See if you have localized content that matches that header. If so, use it in your app manifest. Else, fall back to your default language.

Here is a complete example using Node/Express:

This is a user-level setting, and since the manifest is automatically fetched by the browser based on the meta tag you add to the <head> of the HTML document, it's not possible to directly overwrite the Accept-Language header.

In other words, it won't work hand in hand with a dropdown menu that would allow users to select the language themselves — it'll just still use their browser language.

<link rel="manifest" href="https://example.com/manifest.json">
Enter fullscreen mode Exit fullscreen mode

The above does not offer any way to overwrite headers added to the fetch request for that specific asset.

There's one slightly convoluted way to achieve this: by intercepting the fetch request in the service worker, and then manually changing the Accept-Language. Since you'll need the service worker to be registered for that to work, the very first fetch request for the manifest might not return a JSON file in the right language. Plus, you'll have to make sure it uses the right caching strategy.

Method 3: Progressier

If you're using Progressier, localizing your app manifest is fairly easy. Since the platform is entirely no-code, all you have to do is click on the Localize button next to any of your manifest's parameters, choose a language, and translate. The rest is automatically taken care of for you.

Localizing an app manifest in Progressier

In Progressier, you can localize any of the following manifest parameters: name, short_name, description, start_url, screenshots in any of these 108 languages: English, Afrikaans, Albanian, Amharic, Arabic, Armenian, Azerbaijani, Basque, Belarusian, Bengali, Bosnian, Bulgarian, Catalan, Cebuano, Chinese, Corsican, Croatian, Czech, Danish, Dutch, Esperanto, Estonian, Finnish, French, Frisian, Galician, Georgian, German, Greek, Gujarati, Haitian Creole, Hausa, Hawaiian, Hebrew, Hindi, Hmong, Hungarian, Icelandic, Igbo, Indonesian, Irish, Italian, Japanese, Javanese, Kannada, Kazakh, Khmer, Kinyarwanda, Korean, Kurdish, Kyrgyz, Lao, Latin, Latvian, Lithuanian, Luxembourgish, Macedonian, Malagasy, Malay, Malayalam, Maltese, Maori, Marathi, Mongolian, Myanmar (Burmese), Nepali, Norwegian, Nyanja (Chichewa), Odia (Oriya), Pashto, Persian, Polish, Portuguese, Punjabi, Romanian, Russian, Samoan, Scots Gaelic, Serbian, Sesotho, Shona, Sindhi, Sinhala (Sinhalese), Slovak, Slovenian, Somali, Spanish, Sundanese, Swahili, Swedish, Tagalog (Filipino), Tajik, Tamil, Tatar, Telugu, Thai, Turkish, Turkmen, Ukrainian, Urdu, Uyghur, Uzbek, Vietnamese, Welsh, Xhosa, Yiddish, Yoruba, Zulu.

It also works pretty well with the screenshots property. Progressier comes with a complete solution for designing and managing screenshots.

Questions? Feedback? Please let me know!

Top comments (0)