@hua-labs/i18n-core 2.1.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { validateI18nConfig, Translator } from './chunk-EZL5TNH5.mjs';
2
- export { Translator, serverTranslate, ssrTranslate } from './chunk-EZL5TNH5.mjs';
1
+ import { validateI18nConfig, webPlatformAdapter, Translator } from './chunk-4IYWT7MS.mjs';
2
+ export { Translator, headlessPlatformAdapter, serverTranslate, ssrTranslate, webPlatformAdapter } from './chunk-4IYWT7MS.mjs';
3
3
  import React, { createContext, useState, useEffect, useMemo, useCallback, useContext } from 'react';
4
4
  import { jsx } from 'react/jsx-runtime';
5
5
 
@@ -208,11 +208,12 @@ function resolveInitialLanguage(config) {
208
208
  if (config.defaultLanguage) {
209
209
  return config.defaultLanguage;
210
210
  }
211
- if (typeof window !== "undefined" && navigator?.language) {
212
- const browserLang = navigator.language.slice(0, 2).toLowerCase();
211
+ const adapter = config.platformAdapter ?? webPlatformAdapter;
212
+ const deviceLang = adapter.getDeviceLanguage();
213
+ if (deviceLang) {
213
214
  const supportedCodes = config.supportedLanguages?.map((l) => l.code) ?? [];
214
- if (supportedCodes.includes(browserLang)) {
215
- return browserLang;
215
+ if (supportedCodes.includes(deviceLang)) {
216
+ return deviceLang;
216
217
  }
217
218
  }
218
219
  return config.supportedLanguages?.[0]?.code ?? "ko";
@@ -221,7 +222,9 @@ function I18nProvider({
221
222
  config,
222
223
  children
223
224
  }) {
224
- const [currentLanguage, setCurrentLanguageState] = useState(() => resolveInitialLanguage(config));
225
+ const [currentLanguage, setCurrentLanguageState] = useState(
226
+ () => resolveInitialLanguage(config)
227
+ );
225
228
  const [isLoading, setIsLoading] = useState(true);
226
229
  const [isInitialized, setIsInitialized] = useState(false);
227
230
  const [error, setError] = useState(null);
@@ -242,7 +245,9 @@ function I18nProvider({
242
245
  const translatorLang = translator.getCurrentLanguage();
243
246
  if (translatorLang !== currentLanguage) {
244
247
  if (config.debug) {
245
- console.log(`\u{1F504} [USEI18N] Syncing translator language: ${translatorLang} -> ${currentLanguage} (already initialized)`);
248
+ console.log(
249
+ `\u{1F504} [USEI18N] Syncing translator language: ${translatorLang} -> ${currentLanguage} (already initialized)`
250
+ );
246
251
  }
247
252
  translator.setLanguage(currentLanguage);
248
253
  }
@@ -267,13 +272,18 @@ function I18nProvider({
267
272
  await translator.initialize();
268
273
  setIsInitialized(true);
269
274
  if (config.debug) {
270
- console.log("\u2705 [USEI18N] Translator initialization completed successfully");
275
+ console.log(
276
+ "\u2705 [USEI18N] Translator initialization completed successfully"
277
+ );
271
278
  }
272
279
  } catch (err) {
273
280
  const initError = err;
274
281
  setError(initError);
275
282
  if (config.debug) {
276
- console.error("\u274C [USEI18N] Failed to initialize translator:", initError);
283
+ console.error(
284
+ "\u274C [USEI18N] Failed to initialize translator:",
285
+ initError
286
+ );
277
287
  }
278
288
  setIsInitialized(true);
279
289
  } finally {
@@ -301,7 +311,9 @@ function I18nProvider({
301
311
  const unsubscribe = translator.onLanguageChanged((newLanguage) => {
302
312
  if (newLanguage !== currentLanguage) {
303
313
  if (config.debug) {
304
- console.log(`\u{1F504} [USEI18N] Language changed event: ${currentLanguage} -> ${newLanguage}`);
314
+ console.log(
315
+ `\u{1F504} [USEI18N] Language changed event: ${currentLanguage} -> ${newLanguage}`
316
+ );
305
317
  }
306
318
  setCurrentLanguageState(newLanguage);
307
319
  setTranslationVersion((prev) => prev + 1);
@@ -310,57 +322,59 @@ function I18nProvider({
310
322
  return unsubscribe;
311
323
  }, [translator, isInitialized, currentLanguage, config.debug]);
312
324
  useEffect(() => {
313
- if (!config.autoLanguageSync || typeof window === "undefined") {
325
+ if (!config.autoLanguageSync) {
314
326
  return;
315
327
  }
316
- const handleLanguageChange = (event) => {
317
- const newLanguage = event.detail;
318
- if (typeof newLanguage === "string" && newLanguage !== currentLanguage) {
328
+ const adapter = config.platformAdapter ?? webPlatformAdapter;
329
+ return adapter.onLanguageChange((newLanguage) => {
330
+ if (newLanguage !== currentLanguage) {
319
331
  if (config.debug) {
320
332
  console.log("\u{1F310} Auto language sync:", newLanguage);
321
333
  }
322
334
  setLanguage(newLanguage);
323
335
  }
324
- };
325
- window.addEventListener("huaI18nLanguageChange", handleLanguageChange);
326
- window.addEventListener("i18nLanguageChanged", handleLanguageChange);
327
- return () => {
328
- window.removeEventListener("huaI18nLanguageChange", handleLanguageChange);
329
- window.removeEventListener("i18nLanguageChanged", handleLanguageChange);
330
- };
331
- }, [config.autoLanguageSync, currentLanguage]);
332
- const setLanguage = useCallback(async (language) => {
333
- if (!translator) {
334
- return;
335
- }
336
- const currentLang = translator.getCurrentLanguage();
337
- if (currentLang === language) {
338
- if (config.debug) {
339
- console.log(`\u23ED\uFE0F [USEI18N] Language unchanged, skipping: ${language}`);
340
- }
341
- return;
342
- }
343
- if (config.debug) {
344
- if (config.debug) {
345
- console.log(`\u{1F504} [USEI18N] setLanguage called: ${currentLang} -> ${language}`);
336
+ });
337
+ }, [config.autoLanguageSync, config.platformAdapter, currentLanguage]);
338
+ const setLanguage = useCallback(
339
+ async (language) => {
340
+ if (!translator) {
341
+ return;
342
+ }
343
+ const currentLang = translator.getCurrentLanguage();
344
+ if (currentLang === language) {
345
+ if (config.debug) {
346
+ console.log(`\u23ED\uFE0F [USEI18N] Language unchanged, skipping: ${language}`);
347
+ }
348
+ return;
346
349
  }
347
- }
348
- setIsLoading(true);
349
- try {
350
- translator.setLanguage(language);
351
- setCurrentLanguageState(language);
352
- await new Promise((resolve) => setTimeout(resolve, 0));
353
350
  if (config.debug) {
354
- console.log(`\u2705 [USEI18N] Language changed to ${language}`);
351
+ if (config.debug) {
352
+ console.log(
353
+ `\u{1F504} [USEI18N] setLanguage called: ${currentLang} -> ${language}`
354
+ );
355
+ }
355
356
  }
356
- } catch (error2) {
357
- if (config.debug) {
358
- console.error(`\u274C [USEI18N] Failed to change language to ${language}:`, error2);
357
+ setIsLoading(true);
358
+ try {
359
+ translator.setLanguage(language);
360
+ setCurrentLanguageState(language);
361
+ await new Promise((resolve) => setTimeout(resolve, 0));
362
+ if (config.debug) {
363
+ console.log(`\u2705 [USEI18N] Language changed to ${language}`);
364
+ }
365
+ } catch (error2) {
366
+ if (config.debug) {
367
+ console.error(
368
+ `\u274C [USEI18N] Failed to change language to ${language}:`,
369
+ error2
370
+ );
371
+ }
372
+ } finally {
373
+ setIsLoading(false);
359
374
  }
360
- } finally {
361
- setIsLoading(false);
362
- }
363
- }, [translator, config.debug]);
375
+ },
376
+ [translator, config.debug]
377
+ );
364
378
  const parseKey = useCallback((key) => {
365
379
  const parts = key.split(":");
366
380
  if (parts.length >= 2) {
@@ -368,246 +382,336 @@ function I18nProvider({
368
382
  }
369
383
  return { namespace: "common", key };
370
384
  }, []);
371
- const resolveNestedKey = useCallback((obj, key) => {
372
- if (key in obj && typeof obj[key] === "string") {
373
- return obj[key];
374
- }
375
- const parts = key.split(".");
376
- let current = obj;
377
- for (const part of parts) {
378
- if (current && typeof current === "object" && current !== null && part in current) {
379
- current = current[part];
380
- } else {
381
- return null;
385
+ const resolveNestedKey = useCallback(
386
+ (obj, key) => {
387
+ if (key in obj && typeof obj[key] === "string") {
388
+ return obj[key];
389
+ }
390
+ const parts = key.split(".");
391
+ let current = obj;
392
+ for (const part of parts) {
393
+ if (current && typeof current === "object" && current !== null && part in current) {
394
+ current = current[part];
395
+ } else {
396
+ return null;
397
+ }
382
398
  }
383
- }
384
- return typeof current === "string" ? current : null;
385
- }, []);
386
- const findInSSRTranslations = useCallback((key, targetLang) => {
387
- if (!config.initialTranslations) {
388
- return null;
389
- }
390
- const { namespace, key: actualKey } = parseKey(key);
391
- const ssrTranslations = config.initialTranslations[targetLang]?.[namespace];
392
- if (ssrTranslations) {
393
- const value2 = resolveNestedKey(ssrTranslations, actualKey);
394
- if (value2 !== null) {
395
- return value2;
399
+ return typeof current === "string" ? current : null;
400
+ },
401
+ []
402
+ );
403
+ const findInSSRTranslations = useCallback(
404
+ (key, targetLang) => {
405
+ if (!config.initialTranslations) {
406
+ return null;
396
407
  }
397
- }
398
- const fallbackLang = config.fallbackLanguage || "en";
399
- if (targetLang !== fallbackLang) {
400
- const fallbackTranslations = config.initialTranslations[fallbackLang]?.[namespace];
401
- if (fallbackTranslations) {
402
- const value2 = resolveNestedKey(fallbackTranslations, actualKey);
408
+ const { namespace, key: actualKey } = parseKey(key);
409
+ const ssrTranslations = config.initialTranslations[targetLang]?.[namespace];
410
+ if (ssrTranslations) {
411
+ const value2 = resolveNestedKey(
412
+ ssrTranslations,
413
+ actualKey
414
+ );
403
415
  if (value2 !== null) {
404
416
  return value2;
405
417
  }
406
418
  }
407
- }
408
- return null;
409
- }, [config.initialTranslations, config.fallbackLanguage, parseKey, resolveNestedKey]);
410
- const findInDefaultTranslations = useCallback((key, targetLang) => {
411
- const { namespace, key: actualKey } = parseKey(key);
412
- const defaultTranslations = getDefaultTranslations(targetLang, namespace);
413
- const fallbackTranslations = getDefaultTranslations(config.fallbackLanguage || "en", namespace);
414
- return resolveNestedKey(defaultTranslations, actualKey) || resolveNestedKey(fallbackTranslations, actualKey) || null;
415
- }, [config.fallbackLanguage, parseKey, resolveNestedKey]);
416
- const t = useCallback((key, paramsOrLang, language) => {
417
- if (!translator) {
418
- return key;
419
- }
420
- let params;
421
- let lang;
422
- if (typeof paramsOrLang === "string") {
423
- lang = paramsOrLang;
424
- } else if (typeof paramsOrLang === "object" && paramsOrLang !== null) {
425
- params = paramsOrLang;
426
- lang = language;
427
- }
428
- const targetLang = lang || currentLanguage;
429
- try {
430
- const result = translator.translate(key, params || lang, params ? lang : void 0);
431
- if (result && result !== key && result !== "") {
432
- return result;
419
+ const fallbackLang = config.fallbackLanguage || "en";
420
+ if (targetLang !== fallbackLang) {
421
+ const fallbackTranslations = config.initialTranslations[fallbackLang]?.[namespace];
422
+ if (fallbackTranslations) {
423
+ const value2 = resolveNestedKey(
424
+ fallbackTranslations,
425
+ actualKey
426
+ );
427
+ if (value2 !== null) {
428
+ return value2;
429
+ }
430
+ }
433
431
  }
434
- } catch (error2) {
435
- }
436
- const interpolate = (text) => {
437
- if (!params) return text;
438
- return text.replace(/\{\{(\w+)\}\}/g, (match, k) => {
439
- const value2 = params[k];
440
- return value2 !== void 0 ? String(value2) : match;
441
- });
442
- };
443
- const ssrResult = findInSSRTranslations(key, targetLang);
444
- if (ssrResult) {
445
- return interpolate(ssrResult);
446
- }
447
- const defaultResult = findInDefaultTranslations(key, targetLang);
448
- if (defaultResult) {
449
- return interpolate(defaultResult);
450
- }
451
- if (config.debug) {
452
- return interpolate(key);
453
- }
454
- return "";
455
- }, [translator, config.debug, currentLanguage, config.fallbackLanguage, translationVersion, findInSSRTranslations, findInDefaultTranslations]);
456
- const tAsync = useCallback(async (key, params) => {
457
- if (!translator) {
458
- if (config.debug) {
459
- console.warn("Translator not initialized");
432
+ return null;
433
+ },
434
+ [
435
+ config.initialTranslations,
436
+ config.fallbackLanguage,
437
+ parseKey,
438
+ resolveNestedKey
439
+ ]
440
+ );
441
+ const findInDefaultTranslations = useCallback(
442
+ (key, targetLang) => {
443
+ const { namespace, key: actualKey } = parseKey(key);
444
+ const defaultTranslations = getDefaultTranslations(targetLang, namespace);
445
+ const fallbackTranslations = getDefaultTranslations(
446
+ config.fallbackLanguage || "en",
447
+ namespace
448
+ );
449
+ return resolveNestedKey(
450
+ defaultTranslations,
451
+ actualKey
452
+ ) || resolveNestedKey(
453
+ fallbackTranslations,
454
+ actualKey
455
+ ) || null;
456
+ },
457
+ [config.fallbackLanguage, parseKey, resolveNestedKey]
458
+ );
459
+ const t = useCallback(
460
+ (key, paramsOrLang, language) => {
461
+ if (!translator) {
462
+ return key;
463
+ }
464
+ let params;
465
+ let lang;
466
+ if (typeof paramsOrLang === "string") {
467
+ lang = paramsOrLang;
468
+ } else if (typeof paramsOrLang === "object" && paramsOrLang !== null) {
469
+ params = paramsOrLang;
470
+ lang = language;
471
+ }
472
+ const targetLang = lang || currentLanguage;
473
+ try {
474
+ const result = translator.translate(
475
+ key,
476
+ params || lang,
477
+ params ? lang : void 0
478
+ );
479
+ if (result && result !== key && result !== "") {
480
+ return result;
481
+ }
482
+ } catch (error2) {
460
483
  }
461
- return key;
462
- }
463
- setIsLoading(true);
464
- try {
465
- const result = await translator.translateAsync(key, params);
466
- return result;
467
- } catch (error2) {
468
- if (config.debug) {
469
- console.error("Translation error:", error2);
484
+ const interpolate = (text) => {
485
+ if (!params) return text;
486
+ return text.replace(/\{\{(\w+)\}\}/g, (match, k) => {
487
+ const value2 = params[k];
488
+ return value2 !== void 0 ? String(value2) : match;
489
+ });
490
+ };
491
+ const ssrResult = findInSSRTranslations(key, targetLang);
492
+ if (ssrResult) {
493
+ return interpolate(ssrResult);
470
494
  }
471
- return key;
472
- } finally {
473
- setIsLoading(false);
474
- }
475
- }, [translator, config.debug]);
476
- const tSync = useCallback((key, namespace, params) => {
477
- if (!translator) {
478
- if (config.debug) {
479
- console.warn("Translator not initialized");
495
+ const defaultResult = findInDefaultTranslations(key, targetLang);
496
+ if (defaultResult) {
497
+ return interpolate(defaultResult);
480
498
  }
481
- return key;
482
- }
483
- return translator.translateSync(key, params);
484
- }, [translator, config.debug]);
485
- const getRawValue = useCallback((key, language) => {
486
- if (!translator || !isInitialized) {
487
- return void 0;
488
- }
489
- return translator.getRawValue(key, language);
490
- }, [translator, isInitialized]);
491
- const tArray = useCallback((key, language) => {
492
- if (!translator || !isInitialized) {
493
- return [];
494
- }
495
- return translator.tArray(key, language);
496
- }, [translator, isInitialized, translationVersion, currentLanguage]);
497
- const tPlural = useCallback((key, count, params, language) => {
498
- if (!translator || !isInitialized) {
499
- return key;
500
- }
501
- return translator.tPlural(key, count, params, language);
502
- }, [translator, isInitialized, translationVersion, currentLanguage]);
503
- const debug = useMemo(() => ({
504
- getCurrentLanguage: () => {
505
- try {
506
- return translator?.getCurrentLanguage() || currentLanguage;
507
- } catch {
508
- return currentLanguage;
499
+ if (typeof paramsOrLang === "object" && paramsOrLang !== null && "defaultValue" in paramsOrLang && typeof paramsOrLang.defaultValue === "string") {
500
+ return interpolate(paramsOrLang.defaultValue);
509
501
  }
510
- },
511
- getSupportedLanguages: () => {
512
- try {
513
- return translator?.getSupportedLanguages() || config.supportedLanguages?.map((l) => l.code) || [];
514
- } catch {
515
- return config.supportedLanguages?.map((l) => l.code) || [];
502
+ if (config.debug) {
503
+ return interpolate(key);
516
504
  }
505
+ return "";
517
506
  },
518
- getLoadedNamespaces: () => {
519
- try {
520
- const debugInfo = translator?.debug();
521
- if (debugInfo && debugInfo.loadedNamespaces) {
522
- return Array.from(debugInfo.loadedNamespaces);
523
- }
524
- if (debugInfo && debugInfo.allTranslations) {
525
- const namespaces = /* @__PURE__ */ new Set();
526
- Object.values(debugInfo.allTranslations).forEach((langData) => {
527
- if (langData && typeof langData === "object") {
528
- Object.keys(langData).forEach((namespace) => {
529
- namespaces.add(namespace);
530
- });
531
- }
532
- });
533
- return Array.from(namespaces);
507
+ [
508
+ translator,
509
+ config.debug,
510
+ currentLanguage,
511
+ config.fallbackLanguage,
512
+ translationVersion,
513
+ findInSSRTranslations,
514
+ findInDefaultTranslations
515
+ ]
516
+ );
517
+ const tAsync = useCallback(
518
+ async (key, params) => {
519
+ if (!translator) {
520
+ if (config.debug) {
521
+ console.warn("Translator not initialized");
534
522
  }
535
- return [];
536
- } catch (error2) {
537
- return [];
523
+ return key;
538
524
  }
539
- },
540
- getAllTranslations: () => {
525
+ setIsLoading(true);
541
526
  try {
542
- return translator?.debug()?.allTranslations || {};
527
+ const result = await translator.translateAsync(key, params);
528
+ return result;
543
529
  } catch (error2) {
544
- return {};
530
+ if (config.debug) {
531
+ console.error("Translation error:", error2);
532
+ }
533
+ return key;
534
+ } finally {
535
+ setIsLoading(false);
545
536
  }
546
537
  },
547
- isReady: () => {
548
- try {
549
- return translator?.isReady() || isInitialized;
550
- } catch {
551
- return isInitialized;
538
+ [translator, config.debug]
539
+ );
540
+ const tSync = useCallback(
541
+ (key, namespace, params) => {
542
+ if (!translator) {
543
+ if (config.debug) {
544
+ console.warn("Translator not initialized");
545
+ }
546
+ return key;
552
547
  }
548
+ return translator.translateSync(key, params);
553
549
  },
554
- getInitializationError: () => {
555
- try {
556
- return translator?.getInitializationError() || error;
557
- } catch {
558
- return error;
559
- }
550
+ [translator, config.debug]
551
+ );
552
+ const getRawValue = useCallback(
553
+ (key, language) => {
554
+ if (!translator || !isInitialized) {
555
+ return void 0;
556
+ }
557
+ return translator.getRawValue(key, language);
560
558
  },
561
- clearCache: () => {
562
- try {
563
- translator?.clearCache();
564
- } catch {
559
+ [translator, isInitialized]
560
+ );
561
+ const tArray = useCallback(
562
+ (key, language) => {
563
+ if (!translator || !isInitialized) {
564
+ return [];
565
565
  }
566
+ return translator.tArray(key, language);
566
567
  },
567
- getCacheStats: () => {
568
- try {
569
- const debugInfo = translator?.debug();
570
- if (debugInfo && debugInfo.cacheStats) {
571
- return {
572
- size: debugInfo.cacheSize || 0,
573
- hits: debugInfo.cacheStats.hits || 0,
574
- misses: debugInfo.cacheStats.misses || 0
575
- };
576
- }
577
- return { size: 0, hits: 0, misses: 0 };
578
- } catch (error2) {
579
- return { size: 0, hits: 0, misses: 0 };
580
- }
568
+ [translator, isInitialized, translationVersion, currentLanguage]
569
+ );
570
+ const tPlural = useCallback(
571
+ (key, count, params, language) => {
572
+ if (!translator || !isInitialized) {
573
+ return key;
574
+ }
575
+ return translator.tPlural(key, count, params, language);
581
576
  },
582
- reloadTranslations: async () => {
583
- if (translator) {
584
- setIsLoading(true);
585
- setError(null);
577
+ [translator, isInitialized, translationVersion, currentLanguage]
578
+ );
579
+ const debug = useMemo(
580
+ () => ({
581
+ getCurrentLanguage: () => {
582
+ try {
583
+ return translator?.getCurrentLanguage() || currentLanguage;
584
+ } catch {
585
+ return currentLanguage;
586
+ }
587
+ },
588
+ getSupportedLanguages: () => {
586
589
  try {
587
- await translator.initialize();
588
- } catch (err) {
589
- setError(err);
590
- } finally {
591
- setIsLoading(false);
590
+ return translator?.getSupportedLanguages() || config.supportedLanguages?.map((l) => l.code) || [];
591
+ } catch {
592
+ return config.supportedLanguages?.map((l) => l.code) || [];
593
+ }
594
+ },
595
+ getLoadedNamespaces: () => {
596
+ try {
597
+ const debugInfo = translator?.debug();
598
+ if (debugInfo && debugInfo.loadedNamespaces) {
599
+ return Array.from(debugInfo.loadedNamespaces);
600
+ }
601
+ if (debugInfo && debugInfo.allTranslations) {
602
+ const namespaces = /* @__PURE__ */ new Set();
603
+ Object.values(debugInfo.allTranslations).forEach(
604
+ (langData) => {
605
+ if (langData && typeof langData === "object") {
606
+ Object.keys(langData).forEach((namespace) => {
607
+ namespaces.add(namespace);
608
+ });
609
+ }
610
+ }
611
+ );
612
+ return Array.from(namespaces);
613
+ }
614
+ return [];
615
+ } catch (error2) {
616
+ return [];
617
+ }
618
+ },
619
+ getAllTranslations: () => {
620
+ try {
621
+ return translator?.debug()?.allTranslations || {};
622
+ } catch (error2) {
623
+ return {};
624
+ }
625
+ },
626
+ isReady: () => {
627
+ try {
628
+ return translator?.isReady() || isInitialized;
629
+ } catch {
630
+ return isInitialized;
631
+ }
632
+ },
633
+ getInitializationError: () => {
634
+ try {
635
+ return translator?.getInitializationError() || error;
636
+ } catch {
637
+ return error;
638
+ }
639
+ },
640
+ clearCache: () => {
641
+ try {
642
+ translator?.clearCache();
643
+ } catch {
644
+ }
645
+ },
646
+ getCacheStats: () => {
647
+ try {
648
+ const debugInfo = translator?.debug();
649
+ if (debugInfo && debugInfo.cacheStats) {
650
+ return {
651
+ size: debugInfo.cacheSize || 0,
652
+ hits: debugInfo.cacheStats.hits || 0,
653
+ misses: debugInfo.cacheStats.misses || 0
654
+ };
655
+ }
656
+ return { size: 0, hits: 0, misses: 0 };
657
+ } catch (error2) {
658
+ return { size: 0, hits: 0, misses: 0 };
659
+ }
660
+ },
661
+ reloadTranslations: async () => {
662
+ if (translator) {
663
+ setIsLoading(true);
664
+ setError(null);
665
+ try {
666
+ await translator.initialize();
667
+ } catch (err) {
668
+ setError(err);
669
+ } finally {
670
+ setIsLoading(false);
671
+ }
592
672
  }
593
673
  }
594
- }
595
- }), [translator, currentLanguage, error, isInitialized, config.supportedLanguages]);
596
- const value = useMemo(() => ({
597
- currentLanguage,
598
- setLanguage,
599
- t,
600
- tPlural,
601
- tArray,
602
- tAsync,
603
- tSync,
604
- getRawValue,
605
- isLoading,
606
- error,
607
- supportedLanguages: config.supportedLanguages,
608
- debug,
609
- isInitialized
610
- }), [currentLanguage, setLanguage, t, tPlural, tArray, tAsync, tSync, getRawValue, isLoading, error, config.supportedLanguages, debug, isInitialized]);
674
+ }),
675
+ [
676
+ translator,
677
+ currentLanguage,
678
+ error,
679
+ isInitialized,
680
+ config.supportedLanguages
681
+ ]
682
+ );
683
+ const value = useMemo(
684
+ () => ({
685
+ currentLanguage,
686
+ setLanguage,
687
+ t,
688
+ tPlural,
689
+ tArray,
690
+ tAsync,
691
+ tSync,
692
+ getRawValue,
693
+ isLoading,
694
+ error,
695
+ supportedLanguages: config.supportedLanguages,
696
+ debug,
697
+ isInitialized
698
+ }),
699
+ [
700
+ currentLanguage,
701
+ setLanguage,
702
+ t,
703
+ tPlural,
704
+ tArray,
705
+ tAsync,
706
+ tSync,
707
+ getRawValue,
708
+ isLoading,
709
+ error,
710
+ config.supportedLanguages,
711
+ debug,
712
+ isInitialized
713
+ ]
714
+ );
611
715
  return /* @__PURE__ */ jsx(I18nContext.Provider, { value, children });
612
716
  }
613
717
  function useI18n() {
@@ -617,7 +721,12 @@ function useI18n() {
617
721
  currentLanguage: "ko",
618
722
  setLanguage: () => {
619
723
  },
620
- t: (key) => key,
724
+ t: (key, paramsOrLang) => {
725
+ if (typeof paramsOrLang === "object" && paramsOrLang !== null && "defaultValue" in paramsOrLang && typeof paramsOrLang.defaultValue === "string") {
726
+ return paramsOrLang.defaultValue;
727
+ }
728
+ return key;
729
+ },
621
730
  tPlural: (key) => key,
622
731
  tAsync: async (key) => key,
623
732
  tSync: (key) => key,