UNPKG

@proveanything/smartlinks

Version:

Official JavaScript/TypeScript SDK for the Smartlinks API

288 lines (209 loc) 6.49 kB
# Internationalization (i18n) System This document explains the i18n system for SmartLinks apps, covering URL-based language selection, static translations, and dynamic overrides. --- ## Overview The i18n system supports: - **URL parameter language selection** (`?lang=de`) - Ideal for iframe embedding - **Static translations** in JSON files - Fast, no API calls - **Dynamic overrides** via SmartLinks appConfig - Customer-configurable - **Type-safe translation keys** - Compile-time safety - **Widget support** - Translations can be passed to embedded widgets --- ## Quick Start ### Using Translations in Components ```typescript import { useLanguage } from '@/i18n'; export const MyComponent = () => { const { t, lang } = useLanguage(); return ( <div> <h1>{t('public.title')}</h1> <p>{t('public.description')}</p> <small>Language: {lang}</small> </div> ); }; ``` ### With Parameter Interpolation ```typescript const { t } = useLanguage(); // Translation: "Hello, {{name}}!" t('greeting', { name: 'John' }); // "Hello, John!" ``` --- ## Language Detection Priority The system detects language from multiple sources (in order): | Priority | Source | Example | |----------|--------|---------| | 1 | URL parameter | `?lang=de` | | 2 | localStorage | `smartlinks-lang` key | | 3 | Browser language | `navigator.language` | | 4 | Default | `en` | For iframe apps, the SmartLinks platform passes the language via URL parameter. --- ## File Structure ```text src/i18n/ ├── index.ts # Main exports ├── LanguageContext.tsx # React context + provider ├── types.ts # TypeScript types └── locales/ ├── en.json # English translations ├── de.json # German translations └── fr.json # French translations ``` --- ## Adding New Translations ### 1. Add the Key to Types ```typescript // src/i18n/types.ts export type TranslationKey = | 'common.loading' | 'common.error' | 'myFeature.title' // Add new key | 'myFeature.description'; ``` ### 2. Add Translations to All Locales ```json // src/i18n/locales/en.json { "myFeature.title": "My Feature", "myFeature.description": "Description of my feature" } // src/i18n/locales/de.json { "myFeature.title": "Meine Funktion", "myFeature.description": "Beschreibung meiner Funktion" } ``` ### 3. Use in Components ```typescript const { t } = useLanguage(); return <h1>{t('myFeature.title')}</h1>; ``` --- ## Adding New Languages ### 1. Create the Locale File ```json // src/i18n/locales/es.json { "common.loading": "Cargando...", "common.error": "Algo salió mal", // ... all other keys } ``` ### 2. Import in LanguageContext ```typescript // src/i18n/LanguageContext.tsx import es from './locales/es.json'; const staticTranslations: Record<string, PartialTranslations> = { en: en as PartialTranslations, de: de as PartialTranslations, fr: fr as PartialTranslations, es: es as PartialTranslations, // Add new language }; const SUPPORTED_LANGUAGES = ['en', 'de', 'fr', 'es']; // Add to list ``` --- ## Dynamic Translations (SmartLinks appConfig) For customer-configurable translations, store them in SmartLinks appConfig: ### Config Structure ```json { "i18n": { "supportedLanguages": ["en", "de"], "defaultLanguage": "en", "translations": { "en": { "public.title": "Custom Brand Title", "public.description": "Custom brand description" }, "de": { "public.title": "Benutzerdefinierter Markentitel", "public.description": "Benutzerdefinierte Markenbeschreibung" } } } } ``` ### Loading Dynamic Translations ```typescript import { useCollectionAppConfig } from '@/hooks/useSmartLinksData'; import { LanguageProvider } from '@/i18n'; const App = () => { const { data: config } = useCollectionAppConfig(collectionId, appId); return ( <LanguageProvider dynamicTranslations={config?.i18n?.translations}> <MyApp /> </LanguageProvider> ); }; ``` Dynamic translations override static ones, so customers can customize specific strings while inheriting defaults. --- ## Widgets Widgets receive language context via props rather than React context (since they may run outside the provider). ### Widget Props ```typescript interface SmartLinksWidgetProps { // ... other props lang?: string; translations?: Record<string, string>; } ``` ### Using in Widgets ```typescript import { createTranslator } from '@/i18n'; export const MyWidget: React.FC<SmartLinksWidgetProps> = ({ lang = 'en', translations = {}, ...props }) => { const t = createTranslator(lang, translations); return <div>{t('widget.title')}</div>; }; ``` The `createTranslator` function creates a standalone translation function that doesn't require React context. --- ## URL Examples ``` # English (default) /#/?collectionId=abc&appId=pamphlet # German /#/?collectionId=abc&appId=pamphlet&lang=de # French /#/?collectionId=abc&appId=pamphlet&lang=fr ``` --- ## Best Practices 1. **Use dot notation** for key namespacing: `category.subcategory.key` 2. **Keep translations flat** - avoid nested objects in locale files 3. **Add keys to types.ts first** - ensures type safety 4. **Provide fallbacks** - English is always the fallback language 5. **Test all languages** - Use `?lang=xx` to switch during development --- ## API Reference ### `useLanguage()` Hook to access language context. ```typescript const { lang, // Current language code setLang, // Function to change language t, // Translation function supportedLanguages // Array of supported language codes } = useLanguage(); ``` ### `createTranslator(lang, overrides)` Creates a standalone translation function for widgets. ```typescript const t = createTranslator('de', { 'custom.key': 'Custom value' }); t('common.loading'); // "Laden..." t('custom.key'); // "Custom value" ``` ### `LanguageProvider` React provider component. ```typescript <LanguageProvider dynamicTranslations={optionalOverrides}> <App /> </LanguageProvider> ```