Skip to content

feat(i18n): introduce new design for IntlProvider and useIntl - #5684

Closed
ngolin wants to merge 1 commit into
facebook:mainfrom
ngolin:main
Closed

feat(i18n): introduce new design for IntlProvider and useIntl#5684
ngolin wants to merge 1 commit into
facebook:mainfrom
ngolin:main

Conversation

@ngolin

@ngolin ngolin commented Aug 29, 2026

Copy link
Copy Markdown
Contributor
  • Introduce a dedicated new design of the intl subpackage with IntlProvider, IntlContext and useIntl
  • Show how to achieve compatibility between InternationalizationContext and IntlProvider via getIntlContextValue
  • Demonstrate how to migrate from useTranslator to useIntl using AlertDialog

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Aug 29, 2026
@vercel

vercel Bot commented Aug 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Sep 3, 2026 2:36pm UTC
astryx (canary) Ready Ready Preview Sep 3, 2026 2:36pm UTC

Request Review

@github-actions github-actions Bot added community Authored by a community contributor (not on the eng/design team) needs:code-review High-risk change (new package/component/API) — needs human code review before merge labels Aug 29, 2026
@ngolin
ngolin force-pushed the main branch 3 times, most recently from df270a1 to be195ac Compare August 29, 2026 23:45
@github-actions

github-actions Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

PR Analysis Report

Preview availability: CI did not succeed, so no preview was published.

New Components

intl (@astryxdesign/core)
Metric Value
Bundle Size (ESM) N/A
Bundle Size (CJS) 573B
Lines of Code 79
Source Files 4
Complexity Low (5)
Exports type, type, type, IntlContext, type, type, IntlProvider, useIntl
Props Count N/A
Has Tests No
Has Stories No

Modified Components

AlertDialog (@astryxdesign/core)
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 182 -
Complexity N/A Medium (12) -

Bundle Size Summary

Package Size (ESM) Size (CJS) Gzipped
@astryxdesign/core N/A 4.8KB 1.2KB

Accessibility Audit

Status: No accessibility violations detected.

Visual Regression

Status: Skipped — Broad stable scope is deferred to the daily release gate. It covers 4332 trusted baseline shots instead of recapturing them for this PR. View the report


Generated by PR Enrichment workflow | View full report

@nynexman4464 nynexman4464 left a comment

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.

What do you mean by legacy API? Why is this introducing a new API? Please provide some context and rationale.

@ngolin

ngolin commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

What do you mean by legacy API? Why is this introducing a new API? Please provide some context and rationale.

Hi @nynexman4464, sorry for that, the commit message was AI-generated and didn't capture the full context. I'll provide more details later for your reference.

@ngolin ngolin changed the title refactor(i18n): add IntlProvider and deprecate legacy API feat(i18n): introduce new design for IntlProvider and useIntl Sep 2, 2026
github-actions Bot added a commit that referenced this pull request Sep 2, 2026
@nynexman4464

Copy link
Copy Markdown
Contributor

Introduce a dedicated new design of the intl subpackage with IntlProvider, IntlContext and useIntl

But why what is wrong with the current provider? I'm confused by what this PR is trying to achieve. Are you having issues with the current provider?

@ngolin

ngolin commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

fix(ci): resolve RTL scope to public components #5946

Introduce a dedicated new design of the intl subpackage with IntlProvider, IntlContext and useIntl

But why what is wrong with the current provider? I'm confused by what this PR is trying to achieve. Are you having issues with the current provider?

Hi @nynexman4464, @cixzhang — there’s nothing wrong with the current provider; the existing implementation works. My goal with this change is to make the intl surface clearer and safer for both maintainers and consumers. Concretely I want to:

  1. Let consumers satisfy their needs with the provider from us, avoiding multiple 3rd-party solutions or mixing implementations.
  2. Separate system (astryx/core) messages from user-defined messages so they never get confusing.
  3. Provide a clear, easy-to-understand API that gives consumers more flexibility.
  4. Improve type safety for both maintainers and consumers.

Design notes (high level):

  1. The Provider interface should clearly indicate which fields are for the system and which are user-defined; it should accept only the messages for the current locale (not all locales at once).
interface ProviderValue<MyMessages> {
  locale: string;
  // `overrides` used to replace system component strings/catalog
  overrides: Record<string, string>;
  // `messages` are for the user's own components (not for system catalog)
  messages?: MyMessages;
}
  1. A single hook (useIntl) should expose all capabilities without loss of type safety; users can access both custom messages and system messages.
// for maintainers
const {direction, t} = useIntl();

t('@astryx.pagination.next'); // ok
t('@astryx.not.existed.key'); // error (caught at dev time)

// for consumers
const {messages, t} = useIntl<MyMessages>();
const {currency, discount} = messages; // fully type-safe
t('@astryx.pagination.next'); // use system messages

Demo examples

  1. overrides examples
// Replace the system's default catalog
import zh from 'locales/zh-CN.json';
<Provider locale="zh" overrides={zh} />

// Replace catalog and tweak a few keys
<Provider locale="zh" overrides={{...zh, '@astryx.pagination.next': 'Next'}} />
  1. messages examples (user-defined, can be React nodes or functions; not restricted to ICU strings)
interface MyMessages {
  currency: React.ReactNode;
  discount: (percent: number) => React.ReactNode;
}
const en: MyMessages = {
  currency: <DollarIcon />,
  discount: percent => `${100 - percent}% Off`,
};
const zh: MyMessages = {
  currency: <ChinaYuan />,
  discount: percent => `${percent / 10} 折`,
};

const messages = {en, zh};
const locale = 'zh';

<IntlProvider locale={locale} messages={messages[locale]}>
  <MyComponent price={10} percent={30} />
</IntlProvider>;
  1. useIntl examples (consumer usage with type safety)
const MyComponent = ({price, percent}: {price: number; percent: number}) => {
  const {messages} = useIntl<MyMessages>();
  const {currency, discount} = messages;
  return (
    <span>
      {price}
      {currency}, {discount(percent)}
    </span>
  );
};

- Add a dedicated new design for the intl subpackage with IntlProvider, IntlContext and useIntl
- Demonstrate how to migrate from useTranslator to useIntl using AlertDialog
- Show how to achieve compatibility between InternationalizationContext and IntlProvider via getIntlContextValue
@nynexman4464

Copy link
Copy Markdown
Contributor

I'm still confused by this proposal. It sounds like it follows the principles we set out to design our internationalization system (RFC #3641). It's intended to be used internally, but could be used as the internationalization provider for any app, as outlined in the docs. Granted it's not ideal for that case, but we're not trying to build a fully featured internationalization system. There are lots of good-quality existing systems like react-intl, next-intl, react-i18next, and Lingui that are already more full featured.

messages examples (user-defined, can be React nodes or functions; not restricted to ICU strings)

I don't know if allowing arbitrary react components is something we want. I do see other i18n systems have a "rich text" mode for converting XML like markup to some kind of component, but currently we don't have the need for this in astryx. It adds a lot of complexity for not a lot of benefit at this time.

I appreciate the proposal here, but I'm not sure this is right for astryx at this time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot. community Authored by a community contributor (not on the eng/design team) needs:code-review High-risk change (new package/component/API) — needs human code review before merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants