@shelchin/svelte-i18n
Version:
The last Svelte i18n library you'll ever need. Type-safe, AI-powered, zero-config.
108 lines (107 loc) • 3.44 kB
JavaScript
/**
* Unified i18n initialization for both packages and applications
* Provides consistent API with optional type safety
*/
import { setupI18n, getI18n } from './core/store.svelte.js';
import { configManager } from './core/config-manager.js';
import { registerPackageTranslations } from './services/built-in-loader.js';
/**
* Create a unified i18n configuration with optional type safety
* This function works identically for both packages and applications
*
* @example
* // Without type safety (simple usage)
* export const i18n = createI18n({
* namespace: 'app',
* isMain: true,
* translations
* });
*
* @example
* // With type safety (recommended)
* import type { I18nPath } from './types/i18n-generated';
*
* export const i18n = createI18n<I18nPath>({
* namespace: 'app',
* isMain: true,
* translations
* });
*
* @example
* // In a package
* import translations from './translations.js';
*
* export const i18n = createI18n({
* namespace: 'my-ui-lib',
* translations
* });
*/
export function createI18n(config = {}) {
const namespace = config.namespace || 'app';
const isMain = config.isMain ?? namespace === 'app';
// Register built-in translations if provided
if (config.translations) {
registerPackageTranslations(namespace, config.translations);
}
// Create the base configuration
// Keep namespace as 'app' internally for consistency with registration
const baseConfig = {
...config,
defaultLocale: config.defaultLocale || 'en',
fallbackLocale: config.fallbackLocale || 'en',
namespace: namespace
};
// Register configuration
configManager.register(namespace, baseConfig, isMain);
// Get the effective configuration (may inherit from main app)
const effectiveConfig = configManager.getConfig(namespace) || baseConfig;
// Setup i18n with the effective configuration
const instance = setupI18n(effectiveConfig);
return instance;
}
/**
* Get an existing i18n instance by namespace with optional type safety
* @param namespace - The namespace to get, defaults to 'app'
*
* @example
* // Without type safety
* const i18n = getI18nInstance();
*
* @example
* // With type safety
* import type { I18nPath } from './types/i18n-generated';
* const i18n = getI18nInstance<I18nPath>();
*/
export function getI18nInstance(namespace) {
return getI18n(namespace);
}
/**
* Initialize i18n on the client side
* Call this in your root +layout.svelte
*
* @example
* // In +layout.svelte (both for packages and apps)
* <script>
* import { onMount } from 'svelte';
* import { initI18n } from '@shelchin/svelte-i18n';
* import { i18n } from './i18n';
*
* onMount(() => {
* initI18n(i18n);
* });
* </script>
*/
export async function initI18n(instance) {
// Auto-detect environment and load accordingly
if (typeof window !== 'undefined' && 'clientLoad' in instance && instance.clientLoad) {
// Client-side: load translations
// Don't skip locale restoration - let clientLoad handle it properly
await instance.clientLoad();
}
// Server-side loading is handled in +layout.server.ts if needed
return instance;
}
// Legacy exports for backward compatibility (from typed-unified.ts)
export const createTypedUnifiedI18n = createI18n;
export const getTypedUnifiedI18n = getI18nInstance;
export const initTypedI18n = initI18n;