Skip to main content

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

Getting Help

Questions about best practices?

  • Join our Discord community
  • Check GitHub discussions
  • Contact our developer relations team
  • Review our code examples repository