Troubleshooting
Use the checklist below when translations do not behave as expected.
Catalog changes are not picked up
- Ensure
watch: trueis set when callingcreatePolingo. - Confirm paths line up with the configured
directoryanddomain. For example,directory: './locales'expects./locales/es/messages.po. - Binary
.mocatalogs take precedence over.po. Delete stale.mofiles if you only updated the.poversion.
Lookups return the msgid
- Verify the locale was loaded with
translator.hasLocale(locale); if not, callawait translator.load([locale]). - Check that the catalog contains the exact msgid (gettext comparisons are case sensitive).
- If you use interpolated strings, ensure placeholders match exactly—
{name}is different from{Name}.
Locale detection is wrong in middleware
- Override
localeExtractorto mirror how your app stores locales (cookies, headers, route params). - Log the incoming locale when
debug: trueis enabled to see what the middleware receives. - When dealing with region-specific locales (
es-ES), normalize them before comparing against your supported list.
Compiled JSON is empty
- Run
pnpm exec polingo compile ... --format json --prettyto inspect the output. - Confirm the
.pofile has translated entries—untranslated keys are skipped by default. - If you rely on contexts (
msgctxt), ensure your call uses the matching helper (tp,tnp).
CLI commands fail on CI
- Run
pnpm --filter @polingo/cli buildbefore invokingpnpm exec polingowhen using a bare workspace checkout. - Use the
--cwdflag to point the CLI at the directory that contains your catalogs when running inside containers. - Make sure the checkout preserves executable bits (
git config core.filemode false) so thepolingobinary remains runnable.