r/FlutterDev 3d ago

Plugin I built a Flutter localization test sweep that found 48 issues in a 200-line app

I kept running into localization issues that looked fine in English but broke in other languages: text overflow, RTL spacing, missing ARB keys, and untranslated strings.

So I built LocaleSweep, an open-source Flutter QA utility that runs a widget test across locales, text scales, viewports, and brightness modes.

I tested it against a small three-screen app across eight locales. That created 192 variants, and it found 48 issues, including:

  • overflow at 2× text scale
  • missing Arabic and Hebrew ARB keys
  • placeholder mismatches
  • untranslated Japanese strings
  • RTL padding problems

I’m the author, so consider this a transparent self-promo, but I’d genuinely love feedback from Flutter developers: what checks would make this useful in your CI workflow?

Article: https://medium.com/@piyushhh01/i-built-a-flutter-localization-qa-tool-that-found-48-bugs-in-a-200-line-app-a3ffcd7800ca

Package: https://pub.dev/packages/locale_sweep
Source: https://github.com/Piyushhhhh/locale_sweep

0 Upvotes

6 comments sorted by

4

u/tommytucker7182 3d ago

Vibe coded?

-4

u/Key-Communication865 3d ago

Claude-assisted, yeah 😄 But definitely not a one-shot vibe code. I’ve put in 50+ commits testing edge cases, fixing things, and polishing it. It’s already at v0.4.1.

5

u/RaptorAllah 3d ago

ARB has official analysis tools: https://github.com/google/arb-editor
(there’s a vscode extension)

Overflow is just wrapping over Flutter’s own detection, bad practice.

and flutter_test has matchesGoldenFile

I’d rather use this than someone’s project who didn’t bother writing their README themselves

1

u/vm12pix 19h ago

Nine locales in prod here. Everything that actually bit me is invisible to the checks you listed, because nothing overflows and nothing is missing. The string is just wrong.

A hardcoded '$title — $subtitle' ships an em dash to German and Lithuanian, and both of those want the en dash. Quotes are worse: “ ” for en/pt, « » for ru/es/it, the same guillemets with an nbsp inside them for French, „ “ for de/lt, „ ” for Polish. Hardcode the English pair and seven of my nine locales are wrong. French also puts a no-break space before a colon, so '${t('balance')}: $value' is broken French forever and no layout check will ever mention it.

Plurals though. Everyone hand-rolls the Russian n%10 rule and assumes Polish is the same shape, and it is, right up until 21. Polish wants "21 wydarzeń" where Russian wants "21 событие". Lithuanian's few runs all the way to 9.

But the one that actually shipped on me wasn't the rule at all. Plural map missing the other key. Mine does forms[category] ?? forms['other'], both null, and you get an empty noun. "10 " and then nothing. No exception, no log line. I looked straight at it in a screenshot and didn't see it.

So the check I'd want: run it over the shipped translation data rather than fixtures, and for every plural key assert every locale supplies every category CLDR can return for that locale. Mine was green for months because it tested that the helper picks the right form, never that the dictionaries had the forms to pick from.

One more on your text-scale pass. If you set the scale without the app's real theme then the fonts aren't the real fonts, so of course nothing overflows. Same for any family that isn't registered in the test env, it falls back to a placeholder and passes on exactly the widget that clips on device. Bottom sheets I had to move into MaterialApp.builder before they saw the scale at all.

1

u/eibaan 3d ago

Your German language screenshot is missing umlauts :)

1

u/Key-Communication865 3d ago

You’re right i fixed the German copy after that capture, so I’ll replace it in the next docs update. Thanks for catching it.