@procore/cdn-translations v0.1.1
CDN Translations
A React-based internationalization system that manages translations through a centralized service and CDN. This package provides hooks and utilities for requesting, serving, and managing translations in a distributed system.
Architecture
The package follows a pub/sub architecture using the I18nSystem for communication between components. The main components are:
Translation Requesters (
useRequestTranslationsanduseSaveTranslations)- Components that need translations use the
useRequestTranslationshook - Manages translation state through
useSaveTranslations - Handles translation lifecycle (pending/resolved/rejected)
- Implements timeout handling and cleanup
- Supports both file-based and folder-based translation structures
- Components that need translations use the
Translation Preloader (
usePreloadTranslations)- Proactively loads translations for better performance
- Works alongside the main translation request system
- Helps reduce perceived loading times
- Implements smart caching to prevent duplicate requests
Translation Cache System
- Session-based caching for resolved translations
- Prevents redundant requests through request deduplication
- Maintains translation state across page reloads
- Implements request tracking to handle concurrent requests
- Uses Procore's web-sdk-storage for persistent storage
Event System
- Implements a robust pub/sub system using
SystemEvents - Handles translation resolution and rejection events
- Provides cleanup mechanisms for event subscriptions
- Uses unique identifiers for event tracking
- Implements a robust pub/sub system using
Core Features
Translation Request Flow
- A component requests translations using
useRequestTranslations - The request is handled by
useSaveTranslationswhich:- Checks for translations in nonStandardTranslations
- Applies locale overrides
- Sets up event subscriptions
- Manages request timeouts
- Translations are received through the event system
- The component's state is updated with the received translations
Caching System
- Advanced session-based caching strategy:
- Stores resolved translations in session storage
- Prevents unnecessary refetching of the same translations
- Handles concurrent requests for the same translations
- Persists translations across page reloads
- Implements request tracking to prevent duplicate requests
- Uses Procore's web-sdk-storage for reliable storage
Locale Management
- Supports locale overrides through
getOverrideLocale - Implements fallback list generation with duplicate prevention
- Handles fallback scenarios when translations aren't available
- Maintains translation state for different locales
- Provides consistent fallback hierarchy
Usage
Requesting Translations
import { useRequestTranslations } from '@procore/cdn-translations';
import en from "./path/to/translations/en.json";
import enOwner from "./path/to/translations/en-x-owner.json";
import enBudget from "./path/to/translations/en-budget.json";
function MyComponent() {
const { status, translations } = useRequestTranslations(
{
type: 'file',
absolute_file_path: (locale) => `/path/to/translations/${locale}.json`,
locale: 'es-ES',
},
{ // non-standard translations
en,
'en-US-x-owner': enOwner,
'en-budget': enBudget
}
);
// If you don't handle the pending state, strings will appear in English first,
// then will appear in the requested language when the strings are available
if (status === 'pending') return <Loading />;
return <div>{translations.someKey}</div>;
}Folder-based Structure
import { useRequestTranslations } from '@procore/cdn-translations';
import enCommon from "./path/to/translations/en/common.json";
import enError from "./path/to/translations/en/error.json";
function MyComponent() {
const { status, translations } = useRequestTranslations(
{
type: 'folder',
absolute_file_path: (locale, file_name) =>
`/path/to/translations/${locale}/${file_name}.json`,
locale: 'es-ES',
file_name: 'common',
},
{ // non-standard translations
en: {...enError, ...enCommon},
}
);
// If you don't handle the pending state, strings will appear in English first,
// then will appear in the requested language when the strings are available
if (status === 'pending') return <Loading />;
return <div>{translations.someKey}</div>;
}Error Handling
The system handles various error cases:
- Invalid translation data
- Failed translation requests
- Timeout scenarios (configurable via
OVERDUE_TIMEOUT) - Invalid translation formats
- Missing or invalid locale configurations
Each error case is properly logged and communicated back to the requesting component.
Performance Considerations
- Uses efficient event-based communication
- Handles concurrent requests gracefully
- Implements timeout mechanisms to prevent hanging requests
- Minimizes network requests through caching
- Supports preloading of translations
- Persists translations across page reloads
Configuration
The package can be configured through the Configuration type:
type Configuration = {
locale: string;
} & (
| {
type: 'file';
absolute_file_path: (locale: string) => string;
}
| {
type: 'folder';
absolute_file_path: (locale: string, file_name: string) => string;
file_name: string;
}
);Feature Flags
The package provides functionality to manage the CDN translation feature flag:
import {
setCDNTranslationFeatureFlag,
getCDNTranslationFeatureFlag,
} from '@procore/cdn-translations';
// Enable CDN translations
setCDNTranslationFeatureFlag(true);
// Disable CDN translations
setCDNTranslationFeatureFlag(false);
// Check if CDN translations are enabled
const isEnabled = getCDNTranslationFeatureFlag();The feature flag is stored in session storage and persists across page reloads. This allows for runtime control over whether translations are served through the CDN system.
Constants
The package provides configurable constants:
OVERDUE_TIMEOUT: Timeout duration for translation requests (default: 5000ms)REQUESTING_CACHE_THRESHOLD: Time threshold for request deduplication