#42443·dify

[Refactor/Chore] Preserve the i18next instance across provider rerenders

Author: hyobanCreated Sep 17, 2026Updated Sep 17, 2026
Labelsproject#dify

Self Checks

  • I have read the Contributing Guide and Language Policy.
  • This is only for refactors or chores; if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report, otherwise it will be closed.
  • 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
  • Please do not modify this template :) and fill in all the required fields.

Description

Preserve the i18next instance for the lifetime of a mounted I18nClientProvider.

web/app/components/provider/i18n.tsx calls createI18nextInstance(locale, resource) directly in its render body. The factory in web/i18n-config/client.ts creates and initializes a new instance, including initReactI18next, each time.

A component-level diagnostic using the actual source and fully populated en-US/zh-Hans resource objects:

  1. Invoke the provider with locale="en-US" and capture the instance on its returned I18nextProvider element.
  2. Await instance.changeLanguage('zh-Hans').
  3. Invoke the provider again with identical props.
  4. Compare the returned instances and translations.

Observed result: sameInstance=false, old instance language zh-Hans, new instance language en-US; the translated marker reverts to English.

This diagnostic directly invokes the component function; it is not a mounted React rerender test or an end-to-end reproduction of a particular navigation path. It demonstrates that a render constructs a new instance and loses the previous instance's language state. A mounted regression test and a real triggering path should be established during implementation. Share/embedded chat consumers change language on the existing instance, so its lifetime matters.

Motivation

Unrelated provider rerenders should not recreate the translation context, reinitialize react-i18next, or discard client language state.

Acceptance criteria:

  • A mounted same-props rerender retains the instance and a runtime language change.
  • Intentional locale/resource prop changes have defined, tested behavior.
  • Consumer subscriptions continue working without repeated initialization.
  • Keep SSR request isolation; do not replace per-provider ownership with a process-global singleton.
  • Verify a representative share/embedded-chat language override through a parent rerender.

Additional Context

Observed on a local Dify 1.17.1 development branch based on 06e473015a9a1abb71da88ac0a0e92d96a992008, with local DevTools integration patches; Vinext 1.0.0-beta.10, Vite+ core 0.3.2, Node 24.21.0. Recheck against current main before implementation. Build measurements are diagnostic baselines, not controlled production network benchmarks.