Better Localization in Sitecore XM Cloud: Custom useTranslations Hook for Next.js
Continuing our series on custom hooks for Sitecore XM Cloud with Next.js, this post introduces an optimized solution for handling localization: the useTranslations
hook.
This centralized, modular, and resilient approach simplifies how your application manages dictionary items, ensuring consistency and fallback safety across the app.
๐ This is an improved version of the pattern first introduced in our blog:
Custom Hooks for Next.js in Sitecore XM Cloud
Why We Built useTranslationsIn a large-scale Sitecore XM Cloud project, managing dictionary items can quickly become messy โ especially when translations are used across many components and features.
Instead of scattering useI18n()
and raw keys throughout the app, this custom hook provides:
- โ A centralized translation structure
- โ Fallback values to prevent blank or broken UI
- โ A modular file structure that scales with the app
- โ Cleaner, more readable component code
Organized File Structure
To keep things scalable and developer-friendly, the useTranslations
hook lives inside the /hooks
folder, with all translation logic organized under a /translations
subfolder.
Translations are grouped by domain (e.g., basic UI, billing, meter reads) into separate modules. Each file exports functions like getBasicTranslations
or getBillingTranslations
, which return a set of localized strings.
/hooks/
โโโ useTranslations.ts
โโโ translations/
โโโ basicTranslations.ts
โโโ billingTranslations.ts
โโโ complexTranslations.ts
โโโ profileTranslations.ts
This modular structure ensures better maintainability and keeps related translations together as the app scales.
Built-In Fallbacks
Each translation key in your app is accessed through a helper function that includes a default fallback value:
// Helper function to get translation with fallback
const getTranslation = (i18n: I18nInstance, key: string, fallback: string): string => {
return i18n?.t?.(key) ? i18n.t(key) : fallback;
};
This ensures that even if the Sitecore dictionary hasn't loaded โ or the key is missing โ the app still displays meaningful text to users.
This fallback logic is used inside each translation module you saw in the Organized File Structure section.
Each file exports functions like:
// basicTranslations.ts
export const getBasicTranslations = (i18n) => ({
save: getTranslation(i18n, 'save', 'Save'),
cancel: getTranslation(i18n, 'cancel', 'Cancel'),
continue: getTranslation(i18n, 'continue', 'Continue'),
});
Bringing It All Together in useTranslations.ts
Inside useTranslations.ts
, we import all grouped translation functions and return a single merged object. This allows consumers to access all translations in one place:
import { useI18n } from 'next-localization';
import { getBasicTranslations } from './translations/basicTranslations';
import { getBillingTranslations } from './translations/billingTranslations';
import { getComplexTranslations } from './translations/complexTranslations';
import { getProfileTranslations } from './translations/profileTranslations';
export function useTranslations() {
const i18n = useI18n();
return {
...getBasicTranslations(i18n),
...getBillingTranslations(i18n),
...getComplexTranslations(i18n),
...getProfileTranslations(i18n),
};
}
How to Use It
You can use the hook in two simple ways depending on your style preference:
Option 1: Destructure only what you need
const { save, cancel, loading } = useTranslations();
Option 2: Keep the full object
const translations = useTranslations();
<button>{translations.save}</button>
Both styles work great and are type-safe if you're using TypeScript with shared dictionary types.
Why It Matters
- โ Always shows fallback values โ even offline
- โ Keeps dictionary key access consistent
- โ Eliminates typos and missing key errors
- โ Keeps component logic clean and translation-agnostic
Is It Memory Safe?
Yes โ the useTranslations
hook is fully memory-safe and well-suited for Sitecore XM Cloud projects.
The hook simply merges and returns localized strings using the current i18n
context from next-localization
. It contains no side effects or persistent memory references.
Hereโs why itโs safe:
- โ No event listeners โ nothing is attached to global events or the DOM
- โ No subscriptions โ it doesnโt subscribe to any data streams or observers
- โ No retained references โ translation objects are regenerated per render and not stored between pages
Specific to Sitecore XM Cloud
In Sitecore XM Cloud, dictionary items are delivered via the Layout Service and injected into the i18n
context per page request. Each page loads fresh dictionary data through layoutData.sitecore.dictionary
, so:
- There's no client-side memory retention of previous translations
- The hook always uses the most current data for each page
- Memory usage remains lightweight and predictable
This makes useTranslations
safe to use across multiple components, routes, and renders โ even in large-scale, enterprise-grade apps built with Sitecore XM Cloud and Next.js.
Bonus: Parsing Dictionary Markup
Sometimes, you need to support lightweight HTML markup in dictionary items โ such as:
<b>
for bold text<br>
for line breaks- Placeholder tokens for dynamic values
In these cases, you can pair the useTranslations
hook with our custom parser utility, which safely parses and renders HTML within localized strings.
๐ Formatting Dictionary Items in Sitecore XM Cloud Headless with a Custom Dictionary Text Parser
This approach is ideal for rendering rich text in tooltips, modals, error messages, or descriptions that require flexible formatting.
Final Thoughts on Centralized Localization with useTranslations
in Sitecore XM Cloud
The useTranslations
hook is a clean, scalable, and production-ready approach to managing localization in Sitecore XM Cloud with Next.js.
By centralizing dictionary access, modularizing translation files, and adding built-in fallback support, it simplifies how translations are used throughout your app โ without sacrificing performance or maintainability.
- โ Centralized and consistent usage of translation keys
- โ Safe fallback handling to avoid blank or broken UI
- โ Modular structure that scales with growing feature sets
- โ Fully memory-safe and compatible with Sitecoreโs page-level data model
- โ Easily extendable with markup parsing when richer content is needed
If you're already using the pattern introduced in our earlier Custom Hooks for Next.js in Sitecore XM Cloud blog, this version is a solid evolution โ offering better structure, safety, and flexibility.