• Browser Extension SDK
  • Locales

Localization and Internationalization

Plasmo has built-in support for localization. These concepts should feel familiar to you if you've ever done this in any other Chrome extension.

Plasmo expects your locale files in any of these locations:

  • /locales/{lang}/messages.json
  • /assets/_locales/{lang}/messages.json
  • /assets/locales/{lang}/messages.json

You will need to pick one and stick to it!

English Example

Create a locales/en/messages.json file with a JSON mapping between a unique key and a locale object:

  "extensionName": {
    "message": "with-locales-i18n-en",
    "description": "Name of the extension."
  "extensionDescription": {
    "message": "Example using locales + i18n!",
    "description": "Description of the extension."
  "popup": {
    "message": "Logic is the beginning of wisdom, not the end.",
    "description": "Popup message."

By default, Plasmo picks the first locale alphabetically available as default. However, you can specify a default_locale in your manifest like so:

  "manifest": {
    "default_locale": "en"

Even more powerful, you can use environment variables inside your locale files:

  "popup": {
    "message": "Logic is the beginning of wisdom, not the end. - $PLASMO_PUBLIC_QUOTE_AUTHOR",
    "description": "Popup message."



The locales file are monitored by Plasmo if they existed before the dev server started. Thus, you can change the locales file and see the changes in the browser without restarting the dev server.


With the locale files in place, you can use the i18n API to localize your extension.

Inside source code modules

To get the locale string inside your components, use the i18n API to get the locale message by its key:

import { useState } from "react"
function IndexPopup() {
  const [data, setData] = useState("")
  return (
        display: "flex",
        flexDirection: "column",
        padding: 16
        Welcome to your <a href="https://www.plasmo.com">Plasmo</a> Extension!
      <input onChange={(e) => setData(e.target.value)} value={data} />
export default IndexPopup

Inside package.json and manifest overrides

To reference a locale string inside your manifest overrides, wrap the key inside __MSG_<key>__:

  "name": "with-locales-i18n",
  "displayName": "__MSG_extensionName__",
  "version": "0.0.0",
  "description": "__MSG_extensionDescription__",
  "manifest": {
    "name": "__MSG_extensionName__"

Please refer to the Chrome i18n documentation for more information.

If you'd like to see an example showcasing locale, check out with-locales-i18n in the Plasmo examples repository.