Extracting Every Part of an Oracle APEX URL in JavaScript


I have encountered this problem from time to time, so finally I want to solve it once and for all.
The problem is that I want to fetch every part of the APEX URL. So that I can use it in JS for use in App Development, Plugins, User scripts, etc.
Example problems my include:
I need a URL that starts with either
/pls/apex
(for apex.oracle.com) or/ords
or whatever the middle-ware guys have named the ords serverI need to grab and check the URL parameters for whatever reason
I just need to produce a partial URL in JS
Usually I just find a workaround, something quick, that I think works. But today… enough with that. Please see below a solution that:
Outputs a bunch of APEX URL related attributes
It attempts to reconstruct the URL, comparing against the original, to test its valid
Supports both Classic & Friendly URLs
The idea is that you run the code and take what you need from it.
The Object it outputs returns the following
protocol:
The URL protocol (e.g."https:"
).hostname:
The domain name (e.g."example"
).port:
The port number (e.g."443"
), or an empty string if not specified.fullUrl:
The original full URL passed to the function (orwindow.location.href
by default).fullUrlReconstructed:
The reconstructed URL, built from the protocol, hostname, port, pathname, and search parameters.reconstructionValid:
Boolean indicating if the original URL and the reconstructed URL are identical.isFParamUrl:
Boolean indicating if the URL uses the classic APEXf?p=...
format (non-friendly URL).appId:
The Application ID (from the URL orf?p=...
).pageId:
The Page ID (fromapex.env.APP_PAGE_ID
for classic URLs, or from the friendly URL if available).pageAlias:
The Page Alias (for classic URLs, only set if the value in the URL does not match the real page ID).sessionId:
The Session ID (fromapex.env.APP_SESSION
if available, otherwise from the URL).request:
The request value (from the classic URL’sf?p=...
).workspace:
For friendly URLs: the workspace or language segment after/r/
.appAlias:
For friendly URLs: the application alias segment after/r/
.serviceName:
For classic URLs: the first path segment (e.g.,"ords"
).
For friendly URLs: everything between the domain and/r/
.pathParts:
An array of all path segments in the URL.baseIndex:
The index inpathParts
where the main application-specific segments start (after/r/
for friendly URLs).apexEnv:
The fullapex.env
object (if available), containing Oracle APEX runtime environment details.
Here’s the code:
function parseApexUrl(url = window.location.href) {
const urlObj = new URL(url);
const pathParts = urlObj.pathname.split('/').filter(Boolean);
// Query parameters as array of {key, value}
const paramsArray = Array.from(urlObj.searchParams.entries()).map(
([key, value]) => ({ key, value })
);
// Determine if classic (non-friendly) URL: /ords/f?p=...
const isClassic =
pathParts.length > 0 &&
pathParts[pathParts.length - 1] === 'f' &&
urlObj.searchParams.has('p');
// Oracle APEX environment (if available)
const apexEnv = (typeof apex !== "undefined" && apex.env) ? apex.env : null;
const apexSessionId = apexEnv ? apexEnv.APP_SESSION : null;
const apexPageId = apexEnv ? apexEnv.APP_PAGE_ID : null;
// Classic URL parsing
let workspace = null, appAlias = null, pageAlias = null, serviceName = null, baseIndex = null;
let sessionId = null, pageId = null;
if (isClassic) {
serviceName = pathParts[0] || null;
// Extract appId, pageId/alias, sessionId from the p parameter
const fParam = urlObj.searchParams.get('p');
const parts = fParam ? fParam.split(':') : [];
sessionId = apexSessionId || (parts.length > 2 ? parts[2] : urlObj.searchParams.get('session')) || null;
if (apexPageId && parts[1]) {
if (parts[1] === apexPageId) {
pageId = apexPageId;
pageAlias = null;
} else {
pageId = apexPageId;
pageAlias = parts[1];
}
} else {
pageId = parts[1] || null;
pageAlias = null;
}
} else {
// Friendly URL parsing
let rIndex = pathParts.indexOf('r');
baseIndex = (rIndex !== -1) ? rIndex + 1 : null;
workspace = (baseIndex !== null) ? pathParts[baseIndex] || null : null;
appAlias = (baseIndex !== null) ? pathParts[baseIndex + 1] || null : null;
pageAlias = (baseIndex !== null) ? pathParts[baseIndex + 2] || null : null;
serviceName = (rIndex > 0) ? pathParts.slice(0, rIndex).join('/') : (pathParts[0] || null);
sessionId = apexSessionId || urlObj.searchParams.get('session') || null;
pageId = apexPageId || null;
}
// Reconstruct the full URL
let fullUrlReconstructed;
if (isClassic) {
// For classic URLs, preserve the original query string exactly
const portPart = urlObj.port ? `:${urlObj.port}` : '';
fullUrlReconstructed = `${urlObj.protocol}//${urlObj.hostname}${portPart}${urlObj.pathname}`;
if (urlObj.search) {
fullUrlReconstructed += urlObj.search;
}
} else {
// For friendly URLs, reconstruct as normal
const portPart = urlObj.port ? `:${urlObj.port}` : '';
const reconstructedQuery = paramsArray
.map(param => encodeURIComponent(param.key) + '=' + encodeURIComponent(param.value))
.join('&');
fullUrlReconstructed = `${urlObj.protocol}//${urlObj.hostname}${portPart}${urlObj.pathname}${reconstructedQuery ? '?' + reconstructedQuery : ''}`;
}
// Compare original and reconstructed URLs
const reconstructionValid = (url === fullUrlReconstructed);
return {
protocol: urlObj.protocol,
hostname: urlObj.hostname,
port: urlObj.port,
fullUrl: url,
fullUrlReconstructed: fullUrlReconstructed,
reconstructionValid: reconstructionValid,
paramsArray: paramsArray,
workspace: workspace,
appAlias: appAlias,
pageAlias: pageAlias,
serviceName: serviceName,
pathParts: pathParts,
baseIndex: baseIndex,
sessionId: sessionId,
pageId: pageId,
apexEnv: apexEnv
};
}
Run it with
parseApexUrl()
Example output
{
"protocol": "https:",
"hostname": "apex.oracle.com",
"port": "",
"fullUrl": "https://apex.oracle.com/pls/apex/r/x/employees/employee?p5_empno=7499&session=10815119570851&cs=3irSp6x",
"fullUrlReconstructed": "https://apex.oracle.com/pls/apex/r/x/employees/employee?p5_empno=7499&session=10815119570851&cs=3irSp6x",
"reconstructionValid": true,
"paramsArray": [
{
"key": "p5_empno",
"value": "7499"
},
{
"key": "session",
"value": "10815119570851"
},
{
"key": "cs",
"value": "3irSp6x"
}
],
"workspace": "x",
"appAlias": "employees",
"pageAlias": "employee",
"serviceName": "pls/apex",
"pathParts": [
"pls",
"apex",
"r",
"x",
"employees",
"employee"
],
"baseIndex": 3,
"sessionId": "10815119570851",
"pageId": "5",
"apexEnv": {
"APP_USER": "MATT@EXAMPLE.COM",
"APP_ID": "243414",
"APP_PAGE_ID": "5",
"APP_SESSION": "10815119570851",
"APP_FILES": "r/x/243414/files/static/v6/",
"WORKSPACE_FILES": "r/x/files/static/v21/",
"APEX_VERSION": "24.2.6",
"APEX_BASE_VERSION": "24.2",
"COMPATIBILITY_MODE": 21.2,
"NONCE": "S5VE33y8QiDlH7eWqLzF_A",
"APEX_FILES": "https://static.oracle.com/cdn/apex/24.2.6/"
}
}
Or for something specific, just use dot-notation
parseApexUrl().serviceName
// pls/apex
Of if you want something more specific from it, as AI to convert it for you
Take this script below, can you give me the simpliest form (feweest lines of still readable code)
of returning serviceName
[PASTE ABOVE CODE HERE]
Results in
function getServiceName(url = window.location.href) {
const pathParts = new URL(url).pathname.split('/').filter(Boolean);
const rIndex = pathParts.indexOf('r');
return rIndex > 0 ? pathParts.slice(0, rIndex).join('/') : pathParts[0] || null;
}
ENJOY!
Whats’ the picture? Lambs at Kirkby Overblow - Visit Yorkshire!
Subscribe to my newsletter
Read articles from Matt Mulvaney directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Matt Mulvaney
Matt Mulvaney
With around 20 years on the job, Matt is one of the most experienced software developers at Pretius. He likes meeting new people, traveling to conferences, and working on different projects. He’s also a big sports fan (regularly watches Leeds United, Formula 1, and boxing), and not just as a spectator – he often starts his days on a mountain bike, to tune his mind.