In our last blog post, we explored the critical role of scalable unit conversion and localization in our global expansion efforts. Building on that foundation, we now turn our focus to another vital component: efficient and comprehensive language translation. Our commitment to global accessibility means ensuring that users worldwide can engage with our platform in their preferred languages seamlessly. A key element of this is adapting to regional linguistic nuances. Different areas often use distinct terminologies for the same concepts. We have addressed this by incorporating region-specific translations for certain terms based on their local relevance. This blog will delve into our efforts to streamline language support across our platform, overcoming initial challenges and implementing a robust centralized translation system.
Initial Challenges with Language Support
Initially, our platform did not offer a language picker selection, and translations were handled sporadically. Certain language JSON files were updated based on configuration, translating specific pages. However, this approach led to several issues:
Fragmented Codebases: Different versions of languages require separate codebases, making it difficult to update or modify implementations for new languages.
Cumbersome Translation Process: The vast codebase made adding translation functions for each implementation a tedious and error-prone task.
Implementing a Centralized Translation System
To address these challenges, we introduced a centralized translation system. Our current codebase includes both AngularJS and React implementations, each with its own approach to handling translations:
AngularJS: We use the ng-i18next tag for managing translations.
React: We utilize the react-i18next library for translation handling.
Key features of our new implementation include:
Atom Level Typography Component: Created reusable typography components across the platform for any new implementation.
Custom Translation Components: Developed components that handle translations internally.
Date, Time, and Calendar Translations: Configured libraries like Material-UI, date-fns, and moment.js to set locale based on language configuration.
Language Picker Component: Allows users to select their preferred language, updating the locale across the platform. The language JSON file then translates keys accordingly.
Handle Template-Based Sentences: Simple phrases are easily translated with key-value pairs. However, sentences containing text, units, and symbols require interpolation, a crucial feature of i18n.
Region-specific Terminologies: In the context of the English language, certain words and phrases used in India are different from those used in other countries. For instance, the term “AdBlue,” commonly used in India, is translated as “DEF” in other countries. Another example is “Fuel Theft,” which is known as “Fuel Shrinkage” in the United States and Canadian markets. Our approach has been to handle translations that consider these regional differences, ensuring our platform accurately reflects the local terminologies prevalent in each market.
How to Use the New Implementation
The following code snippets demonstrate our customized translation functions, handling regular texts, texts with special characters, and texts with multiple values.
// Function to translate regular strings
export function translate(str: string, makeShowable: boolean = true) {
if (str) {
return makeShowable ? getShowableString(i18next.t(str)) : i18next.t(str);
} else {
return '';
}
}
// Function to translate strings with units and values
export function translateTemplate(
str: string,
makeShowable: boolean = true,
templateValues = {},
) {
if (str) {
return makeShowable
? getShowableString(i18next.t(str, templateValues))
: i18next.t(str, templateValues);
} else {
return '';
}
}
// Function to handle special characters and translate
export function fixAndTranslate(str: string) {
if (str) {
const fixedStr = str
?.toLowerCase()
?.replace('.', '')
?.replace(/[^a-zA-Z ]/g, ' ')
?.trim();
const translatedStr = translate(fixedStr, false);
return translatedStr === fixedStr ? str : translatedStr;
}
}
// Function to translate an array of strings
export function translateAll(strs: string[], includeFix = true) {
if (strs && strs.length > 0) {
return strs.map(str => {
return includeFix ? fixAndTranslate(str) : translate(str, false);
});
}
}
These customized functions can be used on both angular and react codebases.
Translation Use Case: Handling Text with Units and Values
Consider the translation of a text like “Drive your vehicle at 50+ km/h for 1+ hr.” Given our support for multiple metrics, the speed unit cannot be fixed as km/h. The value (50) will be converted based on current configurations to support m/h units. The speed, speedUnit, and duration values are interpolated in the translated template. Here’s how it works:
Benefits of the Centralized Translation System
The centralized translation system offers several advantages:
Minimal Codebase Modifications: Most pages and features now translate automatically based on additional language JSON files.
Reduced Development Costs: Custom components handling translations internally decrease the effort required for new feature development.
Mandated Translation Handling: Ensures that all new features include proper translation support.
Addressing Implementation Limitations
Despite the benefits, there are some limitations to our current implementation:
Code Release for New Translations: Adding new translations requires a code release since the language JSON files are stored within the UI codebase. This process can delay the deployment of updates.
Understanding Implementation: New developers need to familiarize themselves with the underlying implementation to create custom components for handling translations effectively. This learning curve can impact development speed and efficiency.
Special Characters Handling: The ng-i18next libraries do not handle special characters and symbols out of the box. Given our use cases often include strings with special characters, this requires additional handling within our current implementation.
Future Scope and Enhancements
Looking ahead, we plan to further enhance our translation system by:
Centralized Translation Repository: Establishing a centralized database to store translations for all languages.
Unified Translation Management: Enabling both backend and frontend systems to use the centralized database, reducing redundant work and ensuring consistency.
Backend Translation Handling: Wherever possible, translations should be managed in the backend to ensure a translated API response. This approach centralizes the translation process and reduces the complexity of front-end handling.
By integrating a comprehensive and efficient translation system, we are taking another significant step towards a truly global platform. Stay tuned for more updates on our journey as we continue to innovate and expand our capabilities to meet the needs of our diverse user base.
We’re looking forward to meeting you