Best Practices
Follow these best practices to maximize translation quality, performance, and maintainability when using LiveI18n.
Translation Quality
1. Provide Clear Context
Context is optional but a clear context helps AI models understand the intended meaning and choose appropriate translations.
// ✅ Optional specific context
<LiveText context="shopping cart button">Add to Cart</LiveText>
<LiveText context="navigation menu">Products</LiveText>
<LiveText context="error message">Invalid email address</LiveText>
2. Use Appropriate Tone
Tone affects the formality and style of translations.
// ✅ Match tone to content
<LiveText tone="professional" context="legal document">
Terms and Conditions
</LiveText>
<LiveText tone="friendly" context="welcome message">
Welcome to our community!
</LiveText>
<LiveText tone="urgent" context="error alert">
Action required immediately
</LiveText>
<LiveText tone="celebratory" context="success message">
Congratulations on your purchase!
</LiveText>
3. Keep Text Semantic
Translate meaningful content, not technical identifiers.
// ✅ Good - semantic content
<LiveText context="user action">Save Changes</LiveText>
<LiveText context="status message">Loading your data...</LiveText>
// ❌ Avoid - technical terms
<LiveText>onClick</LiveText>
<LiveText>componentDidMount</LiveText>
<LiveText>HTTP_STATUS_200</LiveText>
4. Dynamic Content
Separating dynamic data from static text yields better caching which reduces latency of translations. However, it is not necessary to separate them if it does not suit your needs.
// ✅ Good - separate static and dynamic content
<div>
<LiveText context="user greeting">Welcome back,</LiveText>
{' '}{user.name}!
</div>
// ⚠️ Doesn't make use of smart caching
<LiveText>Welcome back, {user.name}!</LiveText> // Creates many cache entries
Performance Optimization
1. Leverage Caching Effectively
Use consistent parameters to maximize cache efficiency.
// ✅ Good - consistent parameters
const CONTEXT = 'dashboard title';
const TONE = 'neutral';
<LiveText context={CONTEXT} tone={TONE}>Dashboard</LiveText>
<LiveText context={CONTEXT} tone={TONE}>Dashboard</LiveText>
// ❌ Avoid - inconsistent parameters
<LiveText context="title for dashboard">Dashboard</LiveText>
<LiveText context="dashboard title">Dashboard</LiveText> // Different contexts = different cache keys
2. Optimize Re-renders
Use React optimization techniques to prevent unnecessary re-translations.
import { memo, useMemo } from 'react';
// Memoize components with stable translations
const TranslatedButton = memo(function TranslatedButton({
text,
context,
tone,
onClick
}) {
return (
<button onClick={onClick}>
<LiveText context={context} tone={tone}>
{text}
</LiveText>
</button>
);
});
// Use useMemo for expensive translation logic
function ProductList({ products, language }) {
const translatedProducts = useMemo(() => {
return products.map(product => ({
...product,
translatedName: product.name // Will be translated by LiveText
}));
}, [products, language]);
return (
<div>
{translatedProducts.map(product => (
<ProductCard key={product.id} product={product} />
))}
</div>
);
}
Code Organization
1. Create Translation Constants
Define commonly used translations in constants.
// constants/translations.js
export const COMMON_TEXTS = {
BUTTONS: {
SAVE: 'Save',
CANCEL: 'Cancel',
DELETE: 'Delete',
EDIT: 'Edit'
},
MESSAGES: {
LOADING: 'Loading...',
ERROR: 'An error occurred',
SUCCESS: 'Operation completed successfully'
},
NAVIGATION: {
HOME: 'Home',
ABOUT: 'About',
CONTACT: 'Contact',
PRODUCTS: 'Products'
}
};
export const CONTEXTS = {
BUTTON: 'button',
MESSAGE: 'system-message',
NAVIGATION: 'navigation',
FORM: 'form-field'
};
export const TONES = {
NEUTRAL: 'neutral',
FRIENDLY: 'friendly',
PROFESSIONAL: 'professional',
URGENT: 'urgent'
};
// Usage
import { COMMON_TEXTS, CONTEXTS, TONES } from '../constants/translations';
function SaveButton({ onSave }) {
return (
<button onClick={onSave}>
<LiveText
context={CONTEXTS.BUTTON}
tone={TONES.PROFESSIONAL}
>
{COMMON_TEXTS.BUTTONS.SAVE}
</LiveText>
</button>
);
}
2. Create Reusable Components
Build translation-aware components for consistency.
// components/TranslatedText.jsx
function TranslatedText({
children,
context = 'general',
tone = 'neutral',
className,
...props
}) {
return (
<span className={className} {...props}>
<LiveText context={context} tone={tone}>
{children}
</LiveText>
</span>
);
}
// components/TranslatedButton.jsx
function TranslatedButton({
children,
context = 'button',
tone = 'action',
...props
}) {
return (
<button {...props}>
<LiveText context={context} tone={tone}>
{children}
</LiveText>
</button>
);
}
// components/TranslatedHeading.jsx
function TranslatedHeading({
level = 1,
children,
context = 'heading',
tone = 'informational',
...props
}) {
const Tag = `h${level}`;
return (
<Tag {...props}>
<LiveText context={context} tone={tone}>
{children}
</LiveText>
</Tag>
);
}
3. Implement Translation Wrappers
Create higher-order components or hooks for consistent translation logic.
// hooks/useTranslation.js
import { useMemo } from 'react';
import { CONTEXTS, TONES } from '../constants/translations';
export function useTranslation(defaultContext = CONTEXTS.GENERAL) {
const translate = useMemo(() => ({
button: (text, tone = TONES.ACTION) => (
<LiveText context={CONTEXTS.BUTTON} tone={tone}>
{text}
</LiveText>
),
message: (text, tone = TONES.INFORMATIONAL) => (
<LiveText context={CONTEXTS.MESSAGE} tone={tone}>
{text}
</LiveText>
),
heading: (text, tone = TONES.NEUTRAL) => (
<LiveText context={CONTEXTS.HEADING} tone={tone}>
{text}
</LiveText>
),
custom: (text, context = defaultContext, tone = TONES.NEUTRAL) => (
<LiveText context={context} tone={tone}>
{text}
</LiveText>
)
}), [defaultContext]);
return translate;
}
// Usage
function MyComponent() {
const t = useTranslation();
return (
<div>
{t.heading('Welcome to our app')}
{t.message('Please complete your profile')}
{t.button('Get Started')}
</div>
);
}
Error Handling
1. Implement Fallback Strategies
Always provide fallbacks for translation failures.
import { useState, useEffect } from 'react';
function RobustTranslation({
children,
fallback = children,
context,
tone,
onError
}) {
const [hasError, setHasError] = useState(false);
const handleError = (error) => {
setHasError(true);
console.warn('Translation failed:', error);
onError?.(error);
};
if (hasError) {
return <span>{fallback}</span>;
}
return (
<LiveText
context={context}
tone={tone}
onError={handleError}
>
{children}
</LiveText>
);
}
2. Monitor Translation Health
Track translation performance and errors.
// utils/translationMonitoring.js
class TranslationMonitor {
constructor() {
this.metrics = {
totalTranslations: 0,
failures: 0,
slowTranslations: 0,
cacheHits: 0
};
}
recordTranslation(duration, cached = false, failed = false) {
this.metrics.totalTranslations++;
if (failed) {
this.metrics.failures++;
}
if (cached) {
this.metrics.cacheHits++;
}
if (duration > 1000) { // Slow if > 1 second
this.metrics.slowTranslations++;
}
// Report metrics periodically
if (this.metrics.totalTranslations % 100 === 0) {
this.reportMetrics();
}
}
reportMetrics() {
const { totalTranslations, failures, slowTranslations, cacheHits } = this.metrics;
const report = {
total: totalTranslations,
failureRate: (failures / totalTranslations) * 100,
slowRate: (slowTranslations / totalTranslations) * 100,
cacheHitRate: (cacheHits / totalTranslations) * 100
};
console.log('Translation Metrics:', report);
// Send to analytics service
if (typeof analytics !== 'undefined') {
analytics.track('translation_metrics', report);
}
}
getHealthStatus() {
const { totalTranslations, failures, slowTranslations } = this.metrics;
if (totalTranslations === 0) return 'unknown';
const failureRate = (failures / totalTranslations) * 100;
const slowRate = (slowTranslations / totalTranslations) * 100;
if (failureRate > 10 || slowRate > 20) return 'unhealthy';
if (failureRate > 5 || slowRate > 10) return 'degraded';
return 'healthy';
}
}
export const translationMonitor = new TranslationMonitor();
Testing
1. Test Translation Keys
Ensure all translatable text is properly wrapped.
// utils/testHelpers.js
export function findUntranslatedText(component) {
const untranslatedTexts = [];
// Recursive function to check all text nodes
const checkNode = (node) => {
if (typeof node === 'string' && node.trim()) {
// Check if this text is likely user-facing
if (!/^[A-Z_]+$/.test(node) && // Not a constant
!/^\d+$/.test(node) && // Not just numbers
node.length > 2) { // Meaningful length
untranslatedTexts.push(node);
}
}
if (React.isValidElement(node)) {
if (node.type !== LiveText && node.props.children) {
React.Children.forEach(node.props.children, checkNode);
}
}
};
checkNode(component);
return untranslatedTexts;
}
// Test usage
test('all user-facing text is translated', () => {
const component = <MyComponent />;
const untranslated = findUntranslatedText(component);
expect(untranslated).toHaveLength(0);
});
2. Mock Translations for Testing
Create consistent mocks for reliable testing.
// test/setupTests.js
import { jest } from '@jest/globals';
// Mock the LiveI18n SDK
jest.mock('@livei18n/react-sdk', () => ({
LiveText: ({ children, context, tone, ...props }) => (
<span
data-testid="live-text"
data-context={context}
data-tone={tone}
{...props}
>
{children}
</span>
),
initializeLiveI18n: jest.fn()
}));
// Custom render function with translation context
export function renderWithTranslations(component, options = {}) {
return render(component, {
wrapper: ({ children }) => (
<TranslationTestProvider>
{children}
</TranslationTestProvider>
),
...options
});
}
Security
1. Sanitize User Input
Never translate unsanitized user content.
import DOMPurify from 'dompurify';
function UserGeneratedContent({ content }) {
// ❌ Don't translate unsanitized user content
// <LiveText>{userInput}</LiveText>
// ✅ Sanitize first, then translate if needed
const sanitizedContent = DOMPurify.sanitize(content);
return (
<div>
{/* Most user content shouldn't be translated */}
<span>{sanitizedContent}</span>
{/* Translate UI elements around user content */}
<div className="user-content-footer">
<LiveText context="user-content">Posted by user</LiveText>
</div>
</div>
);
}
2. Validate Translation Contexts
Ensure contexts don't leak sensitive information.
// ✅ Good - generic contexts
<LiveText context="form-field">Password</LiveText>
<LiveText context="error-message">Authentication failed</LiveText>
// ❌ Avoid - contexts with sensitive info
<LiveText context={`user-${userId}-profile`}>Settings</LiveText>
<LiveText context={`api-key-${apiKey}`}>Generate Key</LiveText>
Accessibility
1. Maintain ARIA Attributes
Ensure translations don't break accessibility.
function AccessibleButton({ text, ...props }) {
return (
<button
aria-label={text} // Keep original for screen readers initially
{...props}
>
<LiveText context="button" tone="action">
{text}
</LiveText>
</button>
);
}
2. Handle Text Direction
Consider RTL languages when designing layouts.
function DirectionAwareText({ children, context, tone }) {
return (
<div dir="auto"> {/* Auto-detect text direction */}
<LiveText context={context} tone={tone}>
{children}
</LiveText>
</div>
);
}
Development Workflow
1. Use Environment-Specific Configuration
// config/translation.js
const config = {
development: {
apiKey: process.env.REACT_APP_LIVEI18N_API_KEY_DEV,
customerId: process.env.REACT_APP_LIVEI18N_CUSTOMER_ID_DEV,
debug: true,
cache: { maxSize: 100, ttlHours: 0.1 } // Shorter cache for testing
},
production: {
apiKey: process.env.REACT_APP_LIVEI18N_API_KEY_PROD,
customerId: process.env.REACT_APP_LIVEI18N_CUSTOMER_ID_PROD,
debug: false,
cache: { maxSize: 1000, ttlHours: 24 }
}
};
export default config[process.env.NODE_ENV] || config.development;
2. Create Translation Checklists
Use checklists for consistent implementation:
Pre-Development:
- Identify all user-facing text
- Define context categories
- Plan tone variations
- Set up environment variables
During Development:
- Wrap all user-facing text with
<LiveText>
- Provide appropriate context and tone
- Test with different languages
- Verify caching behavior
Pre-Production:
- Review all translations for quality
- Test performance with production data
- Verify error handling
- Check accessibility compliance
Monitoring & Analytics
1. Track Translation Usage
Monitor which translations are used most frequently.
// Track translation usage for optimization
function trackTranslationUsage(text, context, tone) {
if (typeof analytics !== 'undefined') {
analytics.track('translation_used', {
text_length: text.length,
context,
tone,
timestamp: Date.now()
});
}
}
2. Monitor Performance
Set up performance monitoring for translations.
// Performance monitoring
function TranslationPerformanceMonitor() {
useEffect(() => {
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
if (entry.name.includes('livei18n-translation')) {
const performanceData = {
duration: entry.duration,
startTime: entry.startTime,
cached: entry.duration < 10
};
// Log slow translations
if (entry.duration > 1000) {
console.warn('Slow translation detected:', performanceData);
}
// Send to monitoring service
if (typeof analytics !== 'undefined') {
analytics.track('translation_performance', performanceData);
}
}
});
});
observer.observe({ entryTypes: ['measure'] });
return () => observer.disconnect();
}, []);
return null;
}
Summary Checklist
Quality ✅
- Use specific, meaningful contexts
- Choose appropriate tones
- Separate static from dynamic content
- Provide clear fallbacks
Performance ✅
- Maximize cache efficiency
- Pre-load common translations
- Optimize re-renders
- Monitor performance metrics
Maintainability ✅
- Use translation constants
- Create reusable components
- Implement consistent patterns
- Document translation strategies
Reliability ✅
- Handle errors gracefully
- Test translation coverage
- Monitor health metrics
- Plan for failure scenarios
Next Steps
- Explore caching strategies - Advanced performance optimization
- Try the demo - Test your implementations
- Review React SDK examples - Real-world patterns
Getting Help
Questions about best practices?
- Join our Discord community
- Check GitHub discussions
- Contact our developer relations team
- Review our code examples repository