Mastering Multi-Language Applications in Oracle APEX
Essential Configuration for Robust Internationalization
Oracle APEX provides powerful built-in capabilities for developing multi-lingual applications, enabling developers to deliver localized user experiences with minimal overhead. When properly configured, APEX allows applications to dynamically adapt language, labels, messages, and text based on user preferences or session context.
Supporting multiple languages is essential for modern applications, especially in enterprise and global environments. A robust internationalization strategy improves usability, accessibility, and adoption across diverse user bases.
This article presents a recommended and production-ready approach for setting and managing session language in multi-lingual Oracle APEX applications. We focus on session-based language handling, user preferences, and best practices inspired by community knowledge and real-world implementations.
We will walk through:
- Required globalization settings
- Session language initialization logic
- Authentication handling
- User-driven language selection
- Language repository configuration in Oracle APEX
1. Multi-Language Support in Oracle APEX
Oracle APEX supports multi-language applications through a combination of:
- Application globalization settings
- Translatable text repositories
- Session language context
- User preferences
Key goals of a proper multi-language setup include:
- Consistent language selection across sessions
- Automatic language initialization after login
- Allowing users to explicitly choose their preferred language
- Ensuring all UI text is resolved dynamically
A session-based language strategy is generally preferred, as it provides flexibility and clean separation between users sharing the same application.
2. Translation Utility Package (Required Helper)
To keep the implementation clean and reusable, we centralize all language decision logic (browser language, user preference, explicit override) in a small PL/SQL helper package: ait_translate_util, originally developed by Hayden Hudson.
How it relates to the steps below
This package is the engine used by the application processes/branches described in:
- Step 2 (Public Page Reload Branch): initializes the session language on first contact
- Step 3 (After Authentication Process): re-initializes correctly right after login
- Step 4 (User Language Selector): applies the user’s selection and stores preference
Install this package in the same schema that runs your APEX app, before configuring the processes/branches.
(The full code is in Annex A at the end of the article.)
3. Core Configuration Steps for Session-Based Language Handling
— Source: Based on the "translate-apex" open-source project by Hayden Hudson
3.1 Step 1 – Globalization Settings
Navigate to Application Properties → Globalization and configure:
- Application Language Derived From → Session
This setting instructs APEX to resolve translations dynamically from the current session language rather than a fixed application language.
This is a mandatory step for dynamic multi-language behavior.
3.2 Step 2 – Public Page Reload Branch (Initialize early)
On public (non-authenticated) pages, create a Before Header branch that redirects the page to itself only when the session language has not yet been set.
Branch PL/SQL Condition
declare
l_retval boolean := false;
begin
if apex_util.get_session_lang is null then
ait_translate_util.set_session_lang(p_application_id => :APP_ID);
l_retval := true;
end if;
return l_retval;
end;
Purpose
- Ensures the session language is initialized as early as possible
- Prevents untranslated UI elements on first page load
- Avoids unnecessary redirects once the language is set
Note: This is where your app first uses the ait_translate_util package to decide the initial language.
3.3 Step 3 – After Authentication Process (Re-initialize after login)
Create an After Authentication process at the application level:
begin
ait_translate_util.set_session_lang(p_application_id => :APP_ID);
end;
Why this matters
- Ensures the language is properly re-initialized after login
- Allows language to be derived from:
- User preferences
- Browser language
- Application defaults
- Guarantees a consistent experience for authenticated users
At this point, the same helper decides the final language again, but now with the context of an authenticated user.
3.4 Step 4 – Allowing Users to Set Their Language Preference
To empower users, provide a language selector (e.g., a radio group or select list) on Page 0 (Global Page).
Create a page process that executes:
ait_translate_util.set_session_lang(
p_application_id => :APP_ID,
p_language => :P0_LANG
);
Recommended UI Pattern
- Radio List or Select List
- Display language names (e.g., English, Spanish, Portuguese)
- Store language codes (en, es, pt)
This ensures:
- Immediate language switching
- Persistent session-level preference
- User control over localization
4. Configuring the Oracle APEX Language Repository (Critical Step)
For multi-language support to function correctly, the APEX language repository must be configured and populated.
4.1 Enabling Languages
Navigate to:
Shared Components → Globalization → Translate Application
Here you must:
- Add the target languages (e.g., es, pt, fr)
- Generate the translation repository
4.2 Translating Text
APEX supports translation of:
- Page titles
- Labels
- Button text
- Messages
- Report column headings
- LOV display values
Translations can be:
- Entered manually via the APEX UI
- Imported/exported using XLIFF files
- Managed through automated scripts for large applications
⚠️ Without configuring the language repository, session language changes will occur, but no text will actually be translated.
Implementing multi-language support in Oracle APEX goes far beyond enabling a single setting. A well-designed internationalization strategy requires careful handling of session context, authentication flow, user preferences, and translation repositories.
By combining:
- Session-derived language configuration
- A centralized translation utility package (ait_translate_util)
- Proper initialization logic
- User-controlled language selection
- Correctly configured APEX translation repositories
developers can deliver truly global APEX applications with a seamless and professional user experience.
March 22th, 2026
Author: Samir Chavez
WAYKITECH “We Make Technology Work for You”
Annex A — PL/SQL Helper Package ait_translate_util
— Source: Based on the "translate-apex" open-source project by Hayden Hudson
What this package does (quick summary)
- Detects browser language (HTTP_ACCEPT_LANGUAGE)
- Validates/matches it against the application’s translated languages
- Applies a priority order:
- Explicit language passed by UI selector (p_language)
- Stored user preference (FSP_LANGUAGE_PREFERENCE)
- Browser language (mapped to available translations)
- App primary language (fallback)
- Sets the session language via apex_util.set_session_lang
- Persists preference only for authenticated users
- Clears “mistaken” preference when user is nobody (public)
Package specification
create or replace package ait_translate_util as
procedure set_session_lang(p_application_id in number default v('APP_ID'),
p_language in varchar2 default null);
end ait_translate_util;
/
Package body
create or replace package body ait_translate_util as
gc_scope_prefix constant varchar2(31) := lower($$plsql_unit) || '.';
function get_browser_language (
p_application_id in number default v('APP_ID')
)
return varchar2
is
l_browser_language varchar2(4000);
l_final_browser_language varchar2(5);
begin
select lower(column_value)
into l_browser_language
from table(
apex_string.split(
owa_util.get_cgi_env('HTTP_ACCEPT_LANGUAGE'),
','
)
)
fetch first 1 rows only;
select coalesce(
l1.exact_match,
l2.like_match,
l3.like_match,
aaa.application_primary_language
)
into l_final_browser_language
from dual
left join (
select translated_app_language exact_match
from apex_application_trans_map
where primary_application_id = p_application_id
and translated_app_language = l_browser_language
) l1 on 1 = 1
left join (
select translated_app_language like_match
from apex_application_trans_map
where primary_application_id = p_application_id
and translated_app_language like '%' || l_browser_language || '%'
fetch first 1 rows only
) l2 on 1 = 1
left join (
select translated_app_language like_match
from apex_application_trans_map
where primary_application_id = p_application_id
and l_browser_language like '%' || translated_app_language || '%'
fetch first 1 rows only
) l3 on 1 = 1
left join apex_applications aaa
on aaa.application_id = p_application_id;
return l_final_browser_language;
exception
when others then
raise;
end get_browser_language;
procedure set_session_lang(
p_application_id in number default v('APP_ID'),
p_language in varchar2 default null
)
as
l_preference_language varchar2(5)
:= apex_util.get_preference('FSP_LANGUAGE_PREFERENCE');
l_final_language varchar2(5);
procedure clear_mistaken_public_preference is
begin
if v('APP_USER') = 'nobody'
and l_preference_language is not null
then
apex_util.set_preference(
p_preference => 'FSP_LANGUAGE_PREFERENCE',
p_value => null
);
l_preference_language := null;
end if;
end clear_mistaken_public_preference;
begin
clear_mistaken_public_preference;
l_final_language :=
case
when p_language is not null
then p_language
when l_preference_language is not null
then l_preference_language
else get_browser_language(p_application_id)
end;
apex_util.set_session_lang(p_lang => l_final_language);
if v('APP_USER') != 'nobody'
and p_language is not null
then
apex_util.set_preference(
p_preference => 'FSP_LANGUAGE_PREFERENCE',
p_value => p_language
);
end if;
exception
when others then
raise;
end set_session_lang;
end ait_translate_util;
/