Introduction
In today’s global digital ecosystem, enterprise applications must deliver smooth, intuitive multilingual experiences. For organizations using Pega Infinity, providing users a frictionless way to change language, locale, and layout isn’t just a convenience—it’s a necessity.
The Switch User Locale DX Component, developed as part of the NTDXComponents library, brings a powerful, production-ready solution to this challenge. Designed with enterprise-grade security, accessibility, responsive design, and seamless PCore integration, the component enables users to instantly switch to their preferred locale while ensuring full session persistence, automatic RTL (Right-to-Left) handling, and strict operator verification.
This blog introduces how the Switch Locale component improves user experience, strengthens security, and simplifies multilingual portal management across Pega application.
Switch User Locale Component
A comprehensive, production-ready React component for Pega Infinity that allows users to switch their portal locale and view current locale/timezone information. The component provides a seamless locale switching experience with automatic RTL (Right-to-Left) support, session persistence, responsive design, and enterprise-grade security.
Table of Contents
- Overview
- Features
- Installation
- Configuration
- Props API
- Usage Examples
- Technical Details
- Security Features
- Performance Optimizations
- Storage Mechanism
- RTL Support
- Responsive Design
- Accessibility
- Error Handling
- Browser Compatibility
- Troubleshooting
- Version History
Overview
- The Switch User Locale component is a Pega Infinity widget that enables users to:
View their current locale and timezone (displayed as received from operator object) Select from available locales fetched from a configurable Pega data page
- Switch locales with automatic page refresh and RTL layout support
- Have their locale preference persist during the browser session
- Receive clear feedback through toast notifications
The component is designed with enterprise-grade security, performance optimizations, and accessibility in mind, making it suitable for production use in critical applications.
Features
Core Functionality
- Dynamic Locale Loading: Fetches available locales from a configurable Pega data page
- Locale Switching: Seamlessly switches user locale with automatic page refresh
- Session Persistence: Remembers user’s locale preference during the browser session
- Operator Verification: Always verifies operator identity from PCore to prevent cross-user preferences
- URL Parameter Support: Supports locale persistence via URL parameters
- Cookie Support: Secure cookie-based storage with SameSite=Strict and Secure flags
- Debounced Changes: 500ms debounce prevents rapid successive locale changes
Security Features
- Input Validation: All locale codes are validated using regex to prevent XSS and injection attacks
- Output Sanitization: Locale labels are sanitized before rendering to prevent XSS
- CSRF Protection: Request origin validation and CSRF token retrieval
- Secure Cookies: Uses Secure flag for HTTPS and SameSite=Strict for enhanced security
- Operator Spoofing Prevention: Always verifies operator from PCore, never trusts stored values
User Experience
- Loading States: Progress indicator during initial locale fetch
- Toast Notifications: Success/error feedback with auto-hide (5 seconds)
- Placeholder Option: “Select Locale…” placeholder in dropdown (only shown when no locale selected)
- Error Handling: Graceful error handling with user-friendly messages
- Empty State: Displays “No locales configured for switching” when no locales are available
- Error Boundary: Component-level error boundary prevents crashes
Technical Features
- RTL Support: Automatic Right-to-Left layout for Arabic, Hebrew, Farsi, Urdu, and Yiddish
- Responsive Design: Adapts to smaller screens by hiding locale info on mobile devices (≤768px)
- Format Normalization: Handles both hyphen (fr-CA) and underscore (fr_CA) locale formats
- PCore Integration: Fully integrated with Pega PCore using proper TypeScript types
- Type Safety: Complete TypeScript type definitions for all PCore APIs
- Performance Optimized: Batched sessionStorage operations, exponential backoff polling, memoization
Performance Optimizations
- Batched Storage Operations: Multiple sessionStorage operations are batched for better performance
- Exponential Backoff Polling: PCore availability polling uses exponential backoff (10ms → 100ms) to reduce CPU usage
- Memoization: Expensive computations are memoized to prevent unnecessary recalculations
- Lazy Style Injection: Global styles are injected only when component mounts
- Debounced Locale Changes: Prevents rapid successive locale changes
- Race Condition Prevention: Mount status tracking prevents state updates after unmount
Code Quality
- TypeScript Types: Complete type definitions for PCore API (no any types)
- Error Boundary: React error boundary prevents component crashes
- Standardized Error Handling: Centralized error handling utility
- Named Constants: All magic numbers extracted to named constants
- Clean Code: Well-organized, maintainable code structure
Installation
This component is part of the NTDXComponents library and is available as a Pega Infinity widget.
Prerequisites
- Pega Infinity 25.1.0 or higher
- @pega/cosmos-react-core 8.8.0 or higher
- React 16.8+ (with hooks support)
- TypeScript 4.0+ (for type definitions)
Adding to Your Application
- Ensure the component is included in your Pega application’s component library
- Add the component to your page or case layout through the Pega Designer
- Configure the component properties as needed (see Configuration)
Configuration
The component can be configured through the Pega Designer’s property panel. All configuration options are available in the component’s config.json file.
Configuration Properties
Property | Type | Default | Description |
title | TEXT | “Locale Settings” | Main heading/title of the component |
localesDataPa ge | TEXT | “D_LocaleList” | Name of the Pega data page to fetch locales from |
hideLabel | BOOLEAN | false | Hide the main heading/label of the component |
dropdownLabel | TEXT | “Select Locale” | Label text for the locale dropdown |
hideLocaleInf o | BOOLEAN | false | Hide the current locale and timezone information block |
visibility | VISIBILITY | – | Standard Pega visibility conditions |
Data Page Requirements
The component expects a data page that returns locale information with the following structure:
Data Page Name: Configurable via localesDataPage property (default: D_LocaleList )
Expected Data Structure:
{
“data”: [
{
“Label”: “English (United States)”, “Code”: “en_US”
},
{
“Label”: “Français (Canada)”,
“Code”: “fr_CA”
},
{
)”,اﻟﻌﺮﺑﯿﺔ )اﻟﺴﻌﻮدﯾﺔ” “Label”:
“Code”: “ar_SA”
}
]
}
Required Fields:
- Label : Display name of the locale (shown in dropdown) – will be sanitized for XSS prevention
- Code : Locale code in format language_COUNTRY (e.g., en_US , fr_CA , ar_SA ) – must pass validation
Data Validation:
- Locale codes are validated using regex: /^[a-z]{2,3}([-_][A-Z]{2,3})?([-_][A-Z0- 9]{1,8})?$/i
- Invalid locale codes are filtered out
- Locale labels are sanitized to prevent XSS attacks
Props API
The component accepts the following props (extending PConnFieldProps ):
interface NovitatesNtdxComponentsSwitchLocaleProps extends PConnFieldProp
title?: string; // Component title/heading
localesDataPage?: string; // Data page name for fetching
local dropdownLabel?: string; // Label for the dropdown
hideLocaleInfo?: boolean | string; // Hide locale info block (handles s
hideLabel?: boolean; // Hide main label (from PConnFieldP
label?: string; // Alternative label (from PConnFiel getPConnect?: () => PConnect; // Pega PConnect function
}
Prop Priority
The component uses the following priority order for props:
- Direct props passed to the component
- Props from getPConnect().getConfigProps()
- Default values
Usage Examples
Basic Usage
Add the component to your Pega page with default settings:
{
“type”: “Novitates_NTDXComponents_SwitchLocale”
}
Custom Title
{
“type”: “Novitates_NTDXComponents_SwitchLocale”,
“title”: “Change Language”
}
Custom Data Page
{
“type”: “Novitates_NTDXComponents_SwitchLocale”,
“localesDataPage”: “D_MyCustomLocaleList”
}
Compact Mode (Hide Locale Info)
{
“type”: “Novitates_NTDXComponents_SwitchLocale”,
“hideLocaleInfo”: true,
“hideLabel”: true
}
Full Customization
{
“type”: “Novitates_NTDXComponents_SwitchLocale”,
“title”: “Language Preferences”,
“localesDataPage”: “D_CompanyLocales”,
“dropdownLabel”: “Choose Language”,
“hideLocaleInfo”: false,
“hideLabel”: false
}
Technical Details
Locale Format Handling
The component handles two locale formats:
- Pega Format: Uses hyphens (e.g., en-US , fr-CA , ar-SA )
- Storage Format: Uses underscores (e.g., en_US , fr_CA , ar_SA ) The component automatically converts between formats:
- When storing: Converts hyphens to underscores
- When sending to Pega: Converts underscores to hyphens
Storage Priority
The component uses the following priority order for locale persistence:
- URL Parameter ( ?locale=en_US ) – Highest priority
- SessionStorage (with operator verification) – Primary storage
- Cookie (with operator verification) – Fallback storage
Operator Verification
To prevent locale preferences from persisting across different user sessions:
- Each locale preference is associated with the current operator identifier
- Operator identifier is always retrieved fresh from PCore (never trusts stored value) On logout/login, if the operator changes, the locale preference is cleared
- This ensures users don’t see previous users’ locale preferences
Refresh Mechanism
When a locale is changed:
- RTL Locales: Uses full page reload ( window.location.href ) to ensure proper RTL direction
- LTR Locales: Uses Pega’s refresh mechanism ( pega.desktop.infinity.refreshWindow ) when available
- Fallback: Uses standard page reload if Pega refresh is unavailable
- Debouncing: 500ms debounce prevents rapid successive changes
Loading States
The component manages loading states to prevent:
- Infinite refresh loops
- Multiple simultaneous locale changes
- Race conditions during page loads
Loading state is persisted in sessionStorage to survive page refreshes.
TypeScript Type Safety
The component includes complete TypeScript type definitions for:
- PCore interface with all methods
- PegaEnvironmentInfo interface
- PegaDataPageUtils interface
- PegaStateUtils and
- PegaPubSubUtils interfaces
- Extended Window interface with PCore and pega properties
All PCore access uses type-safe methods with proper null checks.
Security Features
Input Validation
- Locale Code Validation: All locale codes are validated using regex pattern /^[a-z]{2,3}([-
_][A-Z]{2,3})?([-_][A-Z0-9]{1,8})?$/i
- Validation Points: URL parameters, sessionStorage, cookies, data page responses, and user selections
- Invalid Code Handling: Invalid codes are rejected and cleared from storage
Output Sanitization
- XSS Prevention: All locale labels from data pages are sanitized before rendering
- HTML Entity Escaping: Special characters are escaped to prevent XSS attacks
- Safe Rendering: Uses React’s built-in XSS protection with additional sanitization
Cookie Security
- Secure Flag: Cookies use Secure flag when on HTTPS connections
- SameSite=Strict: Prevents cross-site cookie access for enhanced CSRF protection
- Path Restriction: Cookies are set with path=/ for proper scope
CSRF Protection
- Origin Validation: Validates request origin to prevent cross-origin attacks
- CSRF Token Retrieval: Attempts to retrieve CSRF token from PCore or meta tags
- Request Validation: All locale change requests are validated before processing
Operator Verification
- Fresh Operator Check: Always retrieves operator identifier from PCore (never trusts stored value)
- Session Isolation: Clears preferences when operator changes (logout/login scenario)
- Spoofing Prevention: Cannot bypass operator verification by manipulating storage
Performance Optimizations
Batched Storage Operations
- Issue: Multiple sessionStorage operations were causing performance overhead
- Solution: Created batchSessionStorageOperations() helper to batch setItem/removeItem operations
- Impact: Reduced from 62+ individual operations to 16 batched calls (74% reduction)
Exponential Backoff Polling
- Issue: Fixed 10ms polling interval for PCore availability was too aggressive
- Solution: Implemented exponential backoff (10ms → 15ms → 23ms → 35ms → 53ms → 80ms →100ms max)
- Impact: Reduced from up to 500 checks in 5 seconds to 30-40 checks (92% reduction)
Memoization
- Computed Values: All expensive computations use useMemo()
- effectiveDropdownLabel
- effectiveTitle
- effectiveLocalesDataPage
- effectiveHideLocaleInfo
- shouldHideLocaleInfo
- pConnect and configProps
- Impact: Prevents unnecessary recalculations on every render
Debouncing
- Locale Changes: 500ms debounce prevents rapid successive locale changes
- Optimistic Updates: UI updates immediately, actual change is debounced
- Impact: Reduces server load and prevents race conditions
Lazy Style Injection
- Issue: Global styles were injected on module load
- Solution: Styles are now injected only when component mounts
- Impact: Reduces unnecessary DOM manipulation
Race Condition Prevention
- Mount Status Tracking: Uses isMountedRef to track component mount status
- Cleanup: All timeouts and async operations check mount status before state updates
- Impact: Prevents memory leaks and React warnings
Storage Mechanism
SessionStorage Keys
Key | Purpose |
pega_portal_locale_preference | Stores the selected locale code |
pega_portal_locale_operator | Stores the operator identifier for verification |
pega_portal_locale_loading | Indicates if locale change is in progress |
pega_portal_locale_refreshing | Flag to prevent refresh loops |
pega_portal_locale_refresh_timestamp | Timestamp of last refresh |
Key | Purpose |
pega_portal_content_load_refresh_done | Tracks content load refresh completion |
pega_apply_stored_locale_has_run | Prevents multiple executions on page load |
Note: All sessionStorage operations are batched for better performance.
Cookie Storage
- Key: pega_portal_locale
- Format: Hyphen format (e.g., en-US )
- Expiration: 1 year
- SameSite: Strict (enhanced CSRF protection)
- Secure: true (when on HTTPS)
- Path: /
URL Parameters
- Parameter: locale
- Format: Hyphen format (e.g., ?locale=en-US )
- Usage: Automatically added to URL on locale change
- Validation: Locale codes from URL are validated before use
RTL Support
Supported RTL Languages
- The component automatically detects and applies RTL layout for:
- Arabic ( ar )
- Hebrew ( he )
- Farsi/Persian ( fa )
- Urdu ( ur )
- Yiddish ( yi )
RTL Implementation
When an RTL locale is selected:
- HTML dir attribute is set to rtl on <html> and <body> elements
- Full page reload is used to ensure proper RTL rendering
- All UI elements automatically adapt to RTL layout
LTR Restoration
When switching from RTL to LTR:
- HTML dir attribute is explicitly set to ltr
- Ensures proper layout restoration
Responsive Design
Breakpoints
- 768px (Tablet/Mobile): Locale info block (Current Locale and Timezone) is hidden
- >768px (Desktop): Full component with all information displayed
Responsive Behavior
On smaller screens:
- Only the dropdown is shown for a compact interface
- Title/label can be hidden using hideLabel property
- Locale info is automatically hidden via CSS media queries
- Toast notifications adapt to full width on mobile
Accessibility
ARIA Attributes
- Role Attributes: Proper role attributes for all interactive elements
- Aria Labels: Descriptive labels for screen readers
- Aria Live Regions: Toast notifications use aria-live for announcements
- Aria Described By: Links descriptions to form controls
Keyboard Navigation
- Select Dropdown: Fully keyboard navigable
- Keyboard Hints: Screen reader-only text provides navigation instructions
- Focus Management: Proper focus handling throughout the component
Screen Reader Support
- Hidden Text: Screen reader-only text for additional context
- Status Announcements: Loading and error states are announced
- Descriptive Labels: All interactive elements have descriptive labels
Error Handling
Error Boundary
- Component-Level Protection: LocaleSwitchErrorBoundary prevents component crashes.
- User-Friendly Error UI: Displays error message with “Try Again” button
- Error Logging: Errors are logged to console for debugging
Standardized Error Handling
- Centralized Utility: handleError() function standardizes error handling
- Error Types: Handles Error objects, strings, and unknown types
- User Feedback: Integrates with toast notifications for user feedback
Error Scenarios Handled
- PCore unavailability
- Data page fetch failures
- Invalid locale codes
- Network errors
- Component unmount during async operations
Browser Compatibility
Supported Browsers
- Chrome/Edge (latest 2 versions)
- Firefox (latest 2 versions)
- Safari (latest 2 versions)
- Opera (latest 2 versions)
Required Features
- sessionStorage API
- localStorage API (for cookies)
- ES6+ JavaScript features
- React 16.8+ (hooks support)
- TypeScript 4.0+ (for type definitions)
Troubleshooting
Locale Not Changing
Symptoms: Selecting a locale doesn’t change the application language
Solutions:
- Verify the data page is returning locales in the correct format
- Check browser console for errors
- Ensure PCore is available and initialized
- Verify the locale code matches Pega’s supported locales
- Check toast notifications for error messages
Infinite Refresh Loop
Symptoms: Page keeps refreshing continuously
Solutions:
1.Clear browser sessionStorage :
sessionStorage.clear();
2.Clear browser cookies for the domain
3.Check browser console for error messages
4.Verify the locale code is valid
5.Check for refresh flags in sessionStorage
Locales Not Loading
Symptoms: Dropdown shows “No locales configured for switching” or loading indicator persists
Solutions:
- Verify the data page name is correct in component configuration
- Check data page permissions and access
- Verify data page returns data in expected format
- Check browser console for data page errors
- Ensure PCore is available before component mounts
- Check network tab for failed requests
RTL Layout Not Applied
Symptoms: RTL languages don’t display in right-to-left layout
Solutions:
- Verify the locale code starts with an RTL language code ( ar , he , fa , ur , yi )
- Check browser console for errors
- Ensure full page reload occurs (RTL requires page reload)
- Verify HTML dir attribute is being set (check in browser DevTools)
Locale Preference Not Persisting
Symptoms: Locale resets after page refresh
Solutions:
- Check if sessionStorage is enabled in browser
- Verify cookies are enabled
- Check if operator identifier is changing (causes preference to clear)
- Ensure URL parameter is being set correctly
- Verify operator verification is passing
Component Not Appearing
Symptoms: Component doesn’t render on the page
Solutions:
- Check component visibility conditions
- Verify component is properly added to the page layout
- Check browser console for React errors
- Verify all required dependencies are loaded
- Check error boundary for caught errors
Toast Notifications Not Showing
Symptoms: No feedback when changing locale
Solutions:
- Check browser console for errors
- Verify component is mounted (not unmounted during operation)
- Check CSS for toast styles
- Verify z-index is not being overridden
Version History
Version 0.0.1 (Current)
Initial Release Features
- Basic locale switching functionality
- RTL support for Arabic, Hebrew, Farsi, Urdu, Yiddish
- Session persistence with operator verification
- Responsive design for mobile devices
- Configurable data page source
- Loading states and error handling
- URL parameter and cookie support
Security Enhancements
✅ Cookie security flags ( Secure , SameSite=Strict )
✅ Input validation for all locale codes
✅ Output sanitization for locale labels
✅ Enhanced operator verification (always from PCore)
✅ CSRF protection (origin validation, token retrieval)
Performance Optimizations
✅ Batched sessionStorage operations (~74% reduction)
✅ Exponential backoff for PCore polling (~92% reduction)
✅ Memoization of expensive computations
✅ Debounced locale changes (500ms)
✅ Lazy style injection
✅ Race condition prevention
UI/UX Improvements
✅ Toast notifications for success/error feedback
✅ Loading indicator during initial fetch
✅ Conditional placeholder option
✅ Comprehensive ARIA attributes
✅ Keyboard navigation hints
✅ Error boundary for graceful error handling
Code Quality Improvements
✅ Complete TypeScript type definitions (no any types)
✅ Error boundary component
✅ Standardized error handling
✅ Named constants for all magic numbers
✅ Clean, maintainable code structure
Recent Changes
✅ Timezone displayed as-is from operator object (no formatting)
✅ Removed unnecessary timezone formatting logic
Additional Notes
Performance Considerations
- Locales are fetched once on component mount
- Data page query uses pagination (100 items per page)
- Loading states prevent multiple simultaneous requests
- SessionStorage operations are batched for e ciency
- PCore polling uses exponential backoff to reduce CPU usage
- Memoization prevents unnecessary recalculations
Security Considerations
- All locale codes are validated before use
- Locale labels are sanitized to prevent XSS
- Cookies use Secure and SameSite=Strict flags
- Operator verification prevents cross-user preference leakage
- CSRF protection via origin validation
- Request validation before processing
Accessibility Considerations
- Component uses semantic HTML elements
- Select dropdown is fully keyboard navigable
- Loading states are announced to screen readers
- Toast notifications use proper ARIA attributes
- RTL support improves accessibility for RTL language users
- Screen reader-only text provides additional context
TypeScript Support
- Complete type definitions for PCore API
- Extended Window interface with PCore and pega types
- Type guards for safe PCore access
- No any types used
- Full IntelliSense/autocomplete support
Error Resilience
- Error boundary prevents component crashes
- Graceful degradation when PCore is unavailable
- User-friendly error messages
- Standardized error handling
- Proper cleanup on component unmount
Support
For issues, questions, or feature requests, please contact the Novitates development team or refer to the component’s source code documentation.
Component: Novitates_NTDXComponents_SwitchLocale
Organization: Novitates
Version: 0.0.1
Pega Infinity Version: 25.1.1-200
Package Cosmos Version: 8.8.0
Last Updated: 2025-11-12
Conclusion
The Switch Locale component makes multilingual support simple, fast, and secure. With features like operator verification, secure cookie handling, responsive behavior, and automatic RTL switching, it delivers a global-ready user experience for any Pega application. Lightweight, reliable, and enterprise-friendly—this component is built for modern digital platforms.