RTL i18n in cryptocurrency

Making a Persian-friendly layout for MetaMask

Nick Doiron
4 min readJul 8, 2019


In Iraqi Kurdistan I met Ehsan, a blockchain instructor at Re:Coded. We talked about cryptocurrency and discovered we both use the MetaMask wallet.

Back in 2018, I’d answered a bounty challenge, added translation features, and within 6 months MetaMask had 23 language options. Unfortunately none of the languages commonly spoken in Kurdistan (including Arabic, Kurdish, and Persian) were on the list yet. Also discouraging: if someone did translate them, everything would be in an unfriendly left-to-right layout. I offered to get right-to-left CSS working, if only a native speaker would submit a translation to make it worthwhile.

As I continued my trip, Ehsan sent a translation over. This was a breakthrough as I could check if everything was rendering correctly! Then on a long bus ride, I found and flipped every CSS left and right that I could find, wrapping the new CSS in [dir=‘rtl’] & { … }.

I’m going to mention and show bugs, but they are now fixed!

The next day, I built the extension and imported it into my browser. Here we see only minor issues on the home screen:

  • Colorful circle / Identicon menu was made invisible
  • ETH0 needs spacing between value and suffix
  • Heading on transaction list needs whitespace to its right

After researching Identicon, which is full of SVG circle slices, I decided to apply direction: ltr to keep it consistent.

Token search had only minor issues: fixing positioning of the search icon, and setting direction: ltr on token names so the parentheses will enclose correctly.
In the future it’s possible that some tokens will be named in RTL languages... It’s not possible to set direction: auto in CSS, but another option may be to make the top-level element of the transaction list dir=“auto” and text-align: right.

To receive cryptocurrency, you can show someone a QR code or send them your address. The address is rather long so clicking here just copies it to your clipboard.
The abbreviation which typically shows the start of the address (0x38c1b…) was flipped to show the end. This had to be fixed (imagine if you’re sending between two UIs… “is it the account starting with 0x38c1b?” “Don’t know, is it the one ending with 7Ede66?”)

I also reviewed the recovery words screens (not sharing my private key here, so no screenshot). The words are in English, and display in LTR order. But then when you create the account there’s a step to select and re-order them, and recovery requires re-typing them; both steps needed to be restored to left-aligned text and layout.

I made transactions to make sure that the main interface was working.

first pass at RTL UI
  • The arrow from sender to receiver still pointed left-to-right, even though the layout changes had moved sender to the right and receiver to the left. I applied transform: rotate(180deg) to arrows in transactions, confirmations, and regular menu items.
  • Negative numbers and number inputs are a little tricky to get spacing and formatting correct. I found a lesson plan which confirmed that the minus sign should appear between ETH and the number.
  • The copy icon needed some !important CSS to overwrite its padding.
  • The address abbreviation problem reared up again, but in a weirder form (the label meaning “from: ___” is part of the same text node, so I can’t apply CSS to the address alone, and if I flip the direction of the text, the abbreviation will cut off “from” or “to”). I ended up splitting the From/To label into a different <span>, and putting it on its own line with display: block in RTL, so it can appear correctly on the right edge, while the address is visible from the left and cut off on the right… here’s what it looks like in context.


2020 update

There’s a new CC0-licensed project https://github.com/nanexcool/defi18n which is translating a few cryptocurrency terms into all languages — please contribute if you can!

For new recommendations see https://github.com/mapmeld/use-this-now#i18n



Nick Doiron

Web->ML developer and mapmaker.