DEV Community

Cover image for I built supabase-lingo because my "translated" app was still showing English to Japanese users
Shivam
Shivam

Posted on

I built supabase-lingo because my "translated" app was still showing English to Japanese users

So I was building an e-commerce app some time back. I set up i18n, translated all the UI strings, added a language switcher and everything. I thought I was done.

Then a friend in Japan opened it and sent me a screenshot.
The buttons were in Japanese. The navigation was in Japanese. But every single product name and description was in English. It was coming straight from the database. I had translated the UI but the actual content that users care about was still English.
That's when I realized this is a problem every app has and nobody has actually solved it properly.

What I built

supabase-lingo is an npm package that auto-translates your Supabase database content into 10 languages using the Lingo.dev SDK.
It happens automatically the moment data enters your database.
No manual steps. No batch jobs. No changes to your existing schema.

npm install supabase-lingo

How it works

You mark any column in your Postgres schema as @translatable using a column comment:

COMMENT ON COLUMN products.name IS '@translatable';
COMMENT ON COLUMN products.description IS '@translatable';
Enter fullscreen mode Exit fullscreen mode


shell
Then you run one command:

npx supabase-lingo init
Enter fullscreen mode Exit fullscreen mode


plaintext

That's it. Under the hood supabase-lingo does these things:

  1. Scans your DB for @translatable columns
  2. Creates a shadow _lingo_translations table so your original tables are never touched
  3. Sets up Postgres triggers on your tables
  4. Deploys a Supabase Edge Function
  5. Wires everything together

After that every time you insert a row, the trigger fires, the Edge Function calls the Lingo.dev SDK, and your content gets translated into 10 languages automatically.


The shadow table approach

A lot of translation tools modify your original schema by adding columns like name_ja and name_de. That gets messy very quickly.

supabase-lingo keeps a completely separate _lingo_translations table instead:

table_name | row_id | column_name | locale | value
products   | uuid   | name        | ja     | ランニングシューズ
products   | uuid   | name        | ar     | أحذية الجري
products   | uuid   | name        | hi     | रनिंग शूज़
Enter fullscreen mode Exit fullscreen mode


shell

The CLI

The package comes with a CLI so you can see what is happening:

npx supabase-lingo scan      # find @translatable columns
npx supabase-lingo init      # set up triggers and shadow table
npx supabase-lingo translate # bulk translate existing rows
npx supabase-lingo status    # translation coverage per language
Enter fullscreen mode Exit fullscreen mode


shell

The status command is my favorite. It shows a progress bar per language:

products
  ja     ████████████████████ 100%
  ar     ████████████████████ 100%
  hi     ████████████████████ 100%
  de     ████████████████████ 100%
Enter fullscreen mode Exit fullscreen mode

Why Lingo.dev

Google Translate works okay for simple words. But for product descriptions with technical terms it sometimes gives weird results. Lingo.dev gives more natural translations especially for languages like Japanese and Arabic where context matters a lot.
The SDK was also easy to integrate. One API call can translate an entire object at once which made the batch translation in the CLI fast and simple.

The live demo

I built a React storefront to show the whole thing working. You can add a product in English and watch it show up in Japanese, Arabic, Hindi, German, French, Spanish, Chinese, Korean, Portuguese and Russian automatically.
Live demo: https://supabase-lingo-demo.vercel.app
GitHub: https://github.com/ShivamChavan01/supabase-lingo
npm: https://npmjs.com/package/supabase-lingo

What I want to build next

Some things I did not get to finish during the hackathon week:

  • Auto re-translate when source content is updated.
  • A dashboard UI showing translation status across the whole project.
  • Support for more databases beyond Supabase.
  • Webhook notifications when translations are done.

Final thought

The i18n ecosystem has good tools for translating UI strings. But nobody was solving the database content layer. Every marketplace, every e-commerce app, every content platform has this problem right now.

If you are building on Supabase and shipping to international users, give supabase-lingo a try. It is open source, MIT licensed and live on npm.

Top comments (0)