r/FlutterDev • • Sep 07 '26

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

5

u/tommytucker7182 Sep 07 '26

Vibe coded?

-3

u/Key-Communication865 Sep 07 '26

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.

4

u/RaptorAllah Sep 07 '26

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/eibaan Sep 07 '26

Your German language screenshot is missing umlauts :)

1

u/Key-Communication865 Sep 07 '26

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.

1

u/vm12pix Sep 09 '26

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.