Skip to content

fix: pass in an i18next instance by using initReactI18next#23607

Draft
Vibgitcode27 wants to merge 7 commits intocalcom:mainfrom
Vibgitcode27:fix/pass_i18next_instance
Draft

fix: pass in an i18next instance by using initReactI18next#23607
Vibgitcode27 wants to merge 7 commits intocalcom:mainfrom
Vibgitcode27:fix/pass_i18next_instance

Conversation

@Vibgitcode27
Copy link
Contributor

@Vibgitcode27 Vibgitcode27 commented Sep 4, 2025

What does this PR do?

Visual Demo (For contributors especially)

A visual demonstration is strongly recommended, for both the original and new change (video / image - any one).

Video Demo (if applicable):

N/A

Image Demo (if applicable)

  • Before: Console error showing "react-i18next:: You will need to pass in an i18next instance by using initReactI18next"
Screenshot_05-Sep_04-57-40_2115
  • After:
    if NODE_ENV is development
Screenshot_05-Sep_05-05-07_18192

OR
You won't see any log if NODE_ENV is production

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). If N/A, write N/A here and check the checkbox. N/A - This is a bug fix that doesn't require documentation changes
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

Testing Steps:

  1. Environment Setup:

    • No special environment variables required
    • Standard Cal.com development setup
  2. Test Steps:

    cd apps/web
    yarn dev
    visit localhost:3000

Checklist

@Vibgitcode27 Vibgitcode27 requested a review from a team September 4, 2025 23:50
@Vibgitcode27 Vibgitcode27 requested a review from a team as a code owner September 4, 2025 23:50
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 4, 2025

Walkthrough

This PR updates i18n setup across the codebase. It introduces a global lazy-initialized i18next singleton in useLocale.ts with initReactI18next and config-driven defaults. Server and platform i18n utilities now await i18n.init, add interpolation.escapeValue: false, and implement per-locale/namespace i18n instance caching via a Map. Imports are adjusted to include initReactI18next and config loading. The useLocale hook’s return type updates i18n to typeof i18next. No public API changes in server/platform i18n helpers.

Assessment against linked issues

Objective Addressed Explanation
Use initReactI18next and provide an i18next instance to react-i18next to resolve the warning [#23575]
Ensure proper i18n initialization on server and client (await init, consistent interpolation config) [#23575]
Make Description label focus the textarea in new event type modal [CAL-6371] No UI/form changes present; unrelated files touched.

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Add per-locale/namespace i18n instance caching via Map (packages/lib/server/i18n.ts: getTranslation) Caching behavior is not specified in #23575 or CAL-6371.
Add per-locale/namespace i18n instance caching via Map (packages/platform/libraries/i18n.ts: getTranslation) Not required by the linked issues; extends functionality beyond the stated objective.
Introduce global lazy-initialized i18next singleton with config-based defaults, debug flag, and namespace setup (packages/lib/hooks/useLocale.ts) While related to i18n, singleton/config/debug behavior is beyond the minimal requirement of wiring initReactI18next from #23575.

Possibly related PRs

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@graphite-app graphite-app bot requested a review from a team September 4, 2025 23:50
@graphite-app graphite-app bot added the community Created by Linear-GitHub Sync label Sep 4, 2025
@github-actions github-actions bot added i18n area: i18n, translations 🐛 bug Something isn't working labels Sep 4, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Sep 4, 2025

Hey there and thank you for opening this pull request! 👋🏼

We require pull request titles to follow the Conventional Commits specification and it looks like your proposed title needs to be adjusted.

Details:

No release type found in pull request title "fix:p ass in an i18next instance by using initReactI18next". Add a prefix to indicate what kind of release this pull request corresponds to. For reference, see https://www.conventionalcommits.org/

Available types:
 - feat: A new feature
 - fix: A bug fix
 - docs: Documentation only changes
 - style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
 - refactor: A code change that neither fixes a bug nor adds a feature
 - perf: A code change that improves performance
 - test: Adding missing tests or correcting existing tests
 - build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
 - ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
 - chore: Other changes that don't modify src or test files
 - revert: Reverts a previous commit

@vercel
Copy link

vercel bot commented Sep 4, 2025

@Vibgitcode27 is attempting to deploy a commit to the cal Team on Vercel.

A member of the Team first needs to authorize it.

@Vibgitcode27 Vibgitcode27 changed the title fix:p ass in an i18next instance by using initReactI18next fix: pass in an i18next instance by using initReactI18next Sep 4, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/lib/hooks/useLocale.ts (1)

47-47: Fix readiness check.

Object.keys(i18n).length is not a valid readiness signal and will almost always be truthy. Use isInitialized (and optionally presence of the bundle).

-  const isLocaleReady = Object.keys(i18n).length > 0;
+  const activeNs = Array.isArray(namespace) ? namespace[0] : namespace || "common";
+  const isLocaleReady = i18n.isInitialized &&
+    (!!i18n.language) &&
+    (typeof i18n.hasResourceBundle === "function"
+      ? i18n.hasResourceBundle(i18n.language, activeNs)
+      : true);
🧹 Nitpick comments (7)
packages/platform/libraries/i18n.ts (2)

11-12: Type the caches instead of suppressing ESLint.

Avoid any and give both caches precise i18next types; also type the function return as TFunction and the translations as ResourceLanguage.

Apply:

-import { createInstance } from "i18next";
+import { createInstance } from "i18next";
+import type { i18n as I18n, TFunction, ResourceLanguage } from "i18next";

-const translationCache = new Map<string, Record<string, string>>();
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-const i18nInstanceCache = new Map<string, any>();
+const translationCache = new Map<string, ResourceLanguage>();
+const i18nInstanceCache = new Map<string, I18n>();

-export async function loadTranslations(_locale: string, _ns: string) {
+export async function loadTranslations(_locale: string, _ns: string): Promise<ResourceLanguage> {

-export const getTranslation = async (locale: string, ns: string) => {
+export const getTranslation = async (locale: string, ns: string): Promise<TFunction> => {

63-66: Optional: dedupe concurrent inits for same locale-ns.

Two parallel calls can initialize duplicate instances. Consider an “in-flight” Map<string, Promise<I18n>> to coalesce.

Also applies to: 84-86

packages/lib/server/i18n.ts (2)

20-21: Type safety: use i18next types for caches.

Mirror platform changes: type translation cache and instance cache; type getTranslation to return TFunction.

-import { createInstance } from "i18next";
+import { createInstance } from "i18next";
+import type { i18n as I18n, TFunction, ResourceLanguage } from "i18next";

-const translationCache = new Map<string, Record<string, string>>();
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-const i18nInstanceCache = new Map<string, any>();
+const translationCache = new Map<string, ResourceLanguage>();
+const i18nInstanceCache = new Map<string, I18n>();

-export const getTranslation = async (locale: string, ns: string) => {
+export const getTranslation = async (locale: string, ns: string): Promise<TFunction> => {

85-90: Optional: prevent duplicate inits under load.

Add an “in-flight” promise cache to avoid initializing the same locale/ns multiple times concurrently.

Also applies to: 107-110

packages/lib/hooks/useLocale.ts (3)

13-35: Gate global i18next init to the browser.

Initializing the global singleton server-side is unnecessary (server path creates its own instance) and can add overhead in SSR.

-// Initialize global i18next instance if not already initialized
-if (!i18next.isInitialized) {
+// Initialize global i18next instance on the client only
+if (typeof window !== "undefined" && !i18next.isInitialized) {
   i18next.use(initReactI18next).init({
     lng: config?.defaultLocale || "en",
     fallbackLng: "en",
     debug: process.env.NODE_ENV === "development",

58-58: Strongly type the server instances cache.

Improves safety at the return site.

-const serverI18nInstances = new Map();
+const serverI18nInstances = new Map<
+  string,
+  { t: TFunction; isLocaleReady: boolean; i18n: typeof i18next }
+>();

71-86: Server instance: add fallback language for parity.

Add fallbackLng: "en" to match other modules and ensure predictable fallback.

   i18n.init({
     lng: locale,
     resources: {
       [locale]: {
         [ns]: translations,
       },
     },
+    fallbackLng: "en",
     interpolation: {
       escapeValue: false,
     },
   });
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6f05142 and 7fa148f.

📒 Files selected for processing (3)
  • packages/lib/hooks/useLocale.ts (2 hunks)
  • packages/lib/server/i18n.ts (2 hunks)
  • packages/platform/libraries/i18n.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

**/*.ts: For Prisma queries, only select data you need; never use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/lib/hooks/useLocale.ts
  • packages/lib/server/i18n.ts
  • packages/platform/libraries/i18n.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/lib/hooks/useLocale.ts
  • packages/lib/server/i18n.ts
  • packages/platform/libraries/i18n.ts
**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.

Files:

  • packages/lib/hooks/useLocale.ts
  • packages/lib/server/i18n.ts
  • packages/platform/libraries/i18n.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
🧬 Code graph analysis (1)
packages/lib/hooks/useLocale.ts (1)
packages/config/next-i18next.config.d.ts (1)
  • i18n (2-5)
🔇 Additional comments (3)
packages/platform/libraries/i18n.ts (1)

71-82: Good fix: init awaited and escape disabled for React.

Awaiting init and setting interpolation.escapeValue: false matches react-i18next guidance and prevents the console warning.

packages/lib/server/i18n.ts (1)

94-105: LGTM on awaiting init and adding interpolation config.

This aligns server utilities with client behavior and removes the init warning.

packages/lib/hooks/useLocale.ts (1)

15-35: Confirms the core fix.

Using initReactI18next resolves “You will need to pass in an i18next instance” and aligns with react-i18next expectations.

Comment on lines +13 to +35
// Initialize global i18next instance if not already initialized
if (!i18next.isInitialized) {
i18next.use(initReactI18next).init({
lng: config?.defaultLocale || "en",
fallbackLng: "en",
debug: process.env.NODE_ENV === "development",

interpolation: {
escapeValue: false,
},

resources: {
// Start with empty resources, will be populated dynamically
},

react: {
useSuspense: false,
},

ns: ["common"],
defaultNS: "common",
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify CAL-6371 is addressed (Description label focus).

Separate from i18n, please confirm the form label fix landed in this PR. Quick repo scan:


🏁 Script executed:

#!/bin/bash
# Find Description label associations and the textarea id they're targeting
rg -nP -C2 --type=tsx '(htmlFor\s*=\s*["\']description["\']|for="description")|(<textarea[^>]*id\s*=\s*["\']description["\'])|Description</label>' \
  apps packages

# Also check for missing label/textarea linkage in "New Event Type" UI
rg -nP -C3 --type=tsx '(NewEventType|EventType|Description)' apps packages

Length of output: 116


🏁 Script executed:

#!/bin/bash
# Find Description label associations and the textarea id they're targeting
rg -nP -C2 --type=tsx "(htmlFor\s*=\s*['\"]description['\"]|for=\"description\")|(<textarea[^>]*id\s*=\s*['\"]description['\"])|Description</label>" apps packages

# Also check for missing label/textarea linkage in "New Event Type" UI
rg -nP -C3 --type=tsx "(NewEventType|EventType|Description)" apps packages

Length of output: 303


🏁 Script executed:

#!/bin/bash
# Search .tsx files for Description label associations and textarea linkage
rg -nP -C2 '(htmlFor\s*=\s*["\']description["\']|for="description")|(<textarea[^>]*id\s*=\s*["\']description["\'])|Description</label>' -g '*.tsx' apps packages || echo "No matches for Description label associations"

# Search .tsx files in New Event Type UI for missing label/textarea linkage
rg -nP -C3 '(NewEventType|EventType|Description)' -g '*.tsx' apps packages || echo "No matches for NewEventType linkage"

Length of output: 116


🏁 Script executed:

#!/bin/bash
# Search .tsx files for Description label associations and textarea linkage
grep -R -P -n -C2 'htmlFor\s*=\s*['"'"']description['"'"']|for="description"|<textarea[^>]*id\s*=\s*['"'"']description['"'"']|Description</label>' apps packages --include='*.tsx' || echo "No matches for Description label associations"

# Search .tsx files in New Event Type UI for missing label/textarea linkage
grep -R -P -n -C3 '(NewEventType|EventType|Description)' apps packages --include='*.tsx' || echo "No matches for NewEventType linkage"

Length of output: 262557


🏁 Script executed:

#!/bin/bash
# Locate CreateEventTypeDialog component in codebase
grep -R -n 'CreateEventTypeDialog' apps packages --include='*.tsx' || echo 'CreateEventTypeDialog not found'

Length of output: 501


🏁 Script executed:

#!/bin/bash
sed -n '1,200p' packages/features/eventtypes/components/CreateEventTypeDialog.tsx

Length of output: 5302


Ensure Description label is properly linked
No htmlFor="description" on the Description <label> nor matching id="description" on its <textarea> in CreateEventTypeForm.tsx and TeamEventTypeForm.tsx—add the label/input linkage to satisfy CAL-6371.

🤖 Prompt for AI Agents
In packages/lib/hooks/useLocale.ts around lines 13 to 35: the review notes
missing label/input linkage for the Description field in CreateEventTypeForm.tsx
and TeamEventTypeForm.tsx; update both components so the Description <label>
includes htmlFor="description" and the matching <textarea> has id="description"
(use unique ids if multiple forms render on the same page, e.g.,
description-createEventType or description-teamEventType), and ensure any form
libraries or aria attributes reference the same id to satisfy CAL-6371.

@github-actions
Copy link
Contributor

This PR is being marked as stale due to inactivity.

@github-actions github-actions bot added the Stale label Sep 21, 2025
@Vibgitcode27
Copy link
Contributor Author

@Devanshusharma2005 Can you review this?

@github-actions github-actions bot removed the Stale label Sep 22, 2025
Copy link
Contributor

@kart1ka kart1ka left a comment

Choose a reason for hiding this comment

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

LTGM

@github-actions
Copy link
Contributor

github-actions bot commented Oct 7, 2025

This PR is being marked as stale due to inactivity.

@github-actions github-actions bot added the Stale label Oct 7, 2025
@pallava-joshi
Copy link
Contributor

@cubic-dev-ai give review again

@cubic-dev-ai
Copy link
Contributor

cubic-dev-ai bot commented Nov 4, 2025

@cubic-dev-ai give review again

@pallava-joshi I've started the AI code review. It'll take a few minutes to complete.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 3 files

Prompt for AI agents (all 1 issues)

Understand the root cause of the following 1 issues and fix them.


<file name="packages/platform/libraries/i18n.ts">

<violation number="1" location="packages/platform/libraries/i18n.ts:15">
Please keep the default &quot;en-common&quot; seed in translationCache; without it every English lookup waits for fetchWithTimeout to fail, causing multi-second delays whenever WEBAPP_URL is unreachable. Restoring the seed avoids the regression.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 3 files

Copy link
Contributor

@pallava-joshi pallava-joshi left a comment

Choose a reason for hiding this comment

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

can you address the changes suggested by cubic

@pallava-joshi pallava-joshi marked this pull request as draft November 5, 2025 16:13
@Vibgitcode27
Copy link
Contributor Author

@cubic-dev-ai give review again

@cubic-dev-ai
Copy link
Contributor

cubic-dev-ai bot commented Nov 6, 2025

@cubic-dev-ai give review again

@Vibgitcode27 I've started the AI code review. It'll take a few minutes to complete.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 3 files

@Vibgitcode27 Vibgitcode27 marked this pull request as ready for review November 6, 2025 18:58
@Vibgitcode27
Copy link
Contributor Author

@pallava-joshi Addressed cubic suggestions. PR is ready for review.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 3 files

Prompt for AI agents (all 1 issues)

Understand the root cause of the following 1 issues and fix them.


<file name="packages/lib/hooks/useLocale.ts">

<violation number="1" location="packages/lib/hooks/useLocale.ts:17">
The new global i18next initialisation hard-codes `fallbackLng: &quot;en&quot;`, overriding the configured zh→zh-CN fallback in next-i18next.config.js. When the hook falls back to the shared client instance, zh locales will now fall back to English instead of zh-CN, breaking the intended localisation behaviour.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

if (!i18next.isInitialized) {
i18next.use(initReactI18next).init({
lng: config?.defaultLocale || "en",
fallbackLng: "en",
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Nov 6, 2025

Choose a reason for hiding this comment

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

The new global i18next initialisation hard-codes fallbackLng: "en", overriding the configured zh→zh-CN fallback in next-i18next.config.js. When the hook falls back to the shared client instance, zh locales will now fall back to English instead of zh-CN, breaking the intended localisation behaviour.

Prompt for AI agents
Address the following comment on packages/lib/hooks/useLocale.ts at line 17:

<comment>The new global i18next initialisation hard-codes `fallbackLng: &quot;en&quot;`, overriding the configured zh→zh-CN fallback in next-i18next.config.js. When the hook falls back to the shared client instance, zh locales will now fall back to English instead of zh-CN, breaking the intended localisation behaviour.</comment>

<file context>
@@ -1,14 +1,41 @@
+if (!i18next.isInitialized) {
+  i18next.use(initReactI18next).init({
+    lng: config?.defaultLocale || &quot;en&quot;,
+    fallbackLng: &quot;en&quot;,
+    debug: process.env.NODE_ENV === &quot;development&quot;,
+
</file context>
Fix with Cubic

Copy link
Contributor

@pallava-joshi pallava-joshi left a comment

Choose a reason for hiding this comment

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

we have one more.

@pallava-joshi pallava-joshi marked this pull request as draft November 7, 2025 16:02
@devin-ai-integration devin-ai-integration bot added the Low priority Created by Linear-GitHub Sync label Jan 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐛 bug Something isn't working community Created by Linear-GitHub Sync i18n area: i18n, translations Low priority Created by Linear-GitHub Sync size/M Stale

Projects

None yet

Development

Successfully merging this pull request may close these issues.

react-i18next:: You will need to pass in an i18next instance by using initReactI18next

4 participants