Skip to content

feat(l10n): extract strings, add docs, load locales on demand#452

Merged
LeoMcA merged 41 commits intomainfrom
fluent-ast
Mar 11, 2026
Merged

feat(l10n): extract strings, add docs, load locales on demand#452
LeoMcA merged 41 commits intomainfrom
fluent-ast

Conversation

@LeoMcA
Copy link
Copy Markdown
Member

@LeoMcA LeoMcA commented Jul 24, 2025

Gets things to a stage where all strings are - in theory - l10n-able. Next steps will be improving the l10n experience, and further optimising which strings we ship to the client.

The added README is a good source for some of what's going on here.

@LeoMcA LeoMcA requested review from a team and mdn-bot as code owners July 24, 2025 18:29
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jul 24, 2025

86aeb70 was deployed to: https://fred-pr452.review.mdn.allizom.net/

@caugner caugner marked this pull request as draft August 19, 2025 11:35
@caugner
Copy link
Copy Markdown
Contributor

caugner commented Aug 19, 2025

Converted to draft, as it has merge conflicts.

Copy link
Copy Markdown

@bcolsson bcolsson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that more work is happening around localization at some point in the future, but I noticed some major issues that could cause headaches down the road, so adding comments. I'd suggest making changes before asking localizers to translate these. (If the expectation is to use Pontoon, then the complicated Fluent logic wouldn't be supported well either.)

Comment thread l10n/template.ftl
footer-copyright = Portions of this content are ©1998–{ $year } by individual mozilla.org contributors. Content available under <a data-l10n-name="cc">a Creative Commons license</a>.
search-modal-site-search = Site search for <em>{ $query }</em>
site-search-search-stats = Found { $results } documents.
site-search-suggestion-matches =
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this is technically valid fluent it's best to avoid this pattern. This should be two strings - otherwise you can't guarantee that all patterns will have translations (reference).

Typically you want to remove the logic from the strings themselves, so it's preferable to have a -greaterthan and a -equals string then have the logic happening outside of fluent to choose the correct string.

Comment thread l10n/template.ftl
Comment on lines +77 to +104
compat-support-flags =
{ NUMBER($has_added) ->
[one] From version { $version_added }
*[other] { "" }
}{ $has_last ->
[one]
{ NUMBER($has_added) ->
*[zero] Until { $versionLast } users
[one] { " " }until { $versionLast } users
}
*[zero]
{ NUMBER($has_added) ->
*[zero] Users
[one] { " " }users
}
}
{ " " }must explicitly set the <code data-l10n-name="name">{ $flag_name }</code>{ " " }
{ $flag_type ->
*[preference] preference
[runtime_flag] runtime flag
}{ NUMBER($has_value) ->
[one] { " " }to <code data-l10n-name="value">{ $flag_value }</code>
*[other] { "" }
}{ "." }
{ $flag_type ->
[preference] To change preferences in { $browser_name }, visit { $browser_pref_url }.
*[other] { "" }
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is untranslatable. Even in English I barely understand what a final string would look like, so compounding translations with different word order, you'll have a very difficult time to get something comprehensible out of this.

This should be split into multiple strings. E.g.
string-a = From version { version }
string-b = From version { version } until {version} users
ETc.

Comment thread l10n/template.ftl Outdated
compat-experimental = Experimental
compat-nonstandard = Non-standard
compat-no = No
compat-support-full = Full support
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm finding this and multiple other strings with the exact same ID. You'll need to find a way to avoid duplication.

Comment thread l10n/template.ftl
compat-legend-preview = In development. Supported in a pre-release version.
compat-legend-no = { compat-support-no }
compat-legend-unknown = Compatibility unknown
compat-legend-experimental = { compat-experimental }. Expect behavior to change in the future.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I sort of understand why you want to use a reference here and below, but there is the potential for localization issues here. It'd be simpler for localizers to just have the word instead of a message reference.

@caugner caugner removed the request for review from a team October 22, 2025 10:20
@LeoMcA LeoMcA marked this pull request as draft January 30, 2026 16:54
Copy link
Copy Markdown
Contributor

@caugner caugner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just one question: When new strings are added inline, are these automatically added to the Fluent file on pre-commit?

@caugner caugner changed the title chore(l10n): extract strings, add docs, load locales on demand feat(l10n): extract strings, add docs, load locales on demand Mar 11, 2026
@LeoMcA
Copy link
Copy Markdown
Member Author

LeoMcA commented Mar 11, 2026

When new strings are added inline, are these automatically added to the Fluent file on pre-commit?

I wanted to push a commit and say "they are now!" - but unfortunately it's a little more complicated.

I've added a pre-push hook lint run to catch any errors before CI, but in terms of running the extractor on the pre-commit hook, if you have files that are unstaged but which have strings to be scraped, they'll be pulled into the wrong commit.

We should be able to work around that by passing a list of files to the extractor to act on - but that's something I think makes sense for a follow up PR at this point.

Comment thread .lefthook.yml
Comment on lines +48 to +49
- name: lint l10n strings
run: npm run l10n -- --lint
Copy link
Copy Markdown
Contributor

@caugner caugner Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given how fast this runs, should we not also run it on pre-commit?

% time npm run l10n -- --lint

> @mdn/fred@2.2.1 l10n
> node l10n/cli.js --lint

npm run l10n -- --lint  0.64s user 0.07s system 113% cpu 0.627 total

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The glob option supports multiple values, so we could run it only when relevant files were changed.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The failure case is something like:

  • add string to components/a.js
  • add string to components/b.js
  • stage a.js
  • commit
  • new strings from both a and b are in template.ftl

@LeoMcA LeoMcA merged commit 07cb9c3 into main Mar 11, 2026
13 checks passed
@LeoMcA LeoMcA deleted the fluent-ast branch March 11, 2026 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants