human readable URLs in Oracle APEX – Part 3

In the first two parts of this blogpost series we covered the basics and the technique on how to provide nice/friendly/readable URLs for a public APEX Application.

If you haven’t read the other two parts, please go back and read part 1, then read part 2. Done? Ok, lets continue.

Again here the links for two examples: the Sample Database Application which will be used as example in this post and the click-click Website (which is multilingual, just change /en/ to /de/ in the URL).

This Blogpost will cover the necessary changes in an APEX Application, to work with human readable URLs.

Public Pages

Really important is that all pages in your application are set to “Public”

and that the active Authentication Scheme isn’t No Authentication (using DAD), since that would lead to problems in combination with the APEX Listener with APEX 4.2.3 and below (Bug 17796199 fixed in 4.2.4).


In the Authorization Scheme go to the cookie section and set a cookie path, matching your base URL. On this is /pls/apex/, on the click-click Website it is /web/.

The Path is important, otherwise a new cookie (and new APEX session) would be created when visiting /home at first and /customers after that.

The Cookie Name is optional, you can also leave that blank.

Target is URL

Above we prepared the application to support our new URL structure. Now its time to walk through our application and change every Button, List Item, Branch and whatever Link you may have to use the new and shiny URLs.

A good idea here is to define an application substitution string which holds the base URL. In my demo I have defined a substitution string called G_URL which is set to /pls/apex/hrurl. In URL Targets I then can use it like this: &G_URL./customer/#CUSTOMER_ID#

Base URL to support Form Submits

So far everything works fine, we can call and show all our Pages. But when trying to submit (save) a form we get an error saying that wwv_flow.accept doesn’t exist.

This happens, because wwv_flow.accept is simply appended to the end of the active URL. e.g.

The easy workaround is to define a Base URL using a simple HTML Meta Definition.

Can you see it? It is this simple command: <base href=”/pls/apex/” />

UPDATE: older IE versions (yes, some people still call it a browser) need a fully referenced base href, like: <base href=”” />

Now wwv_flow.accept is appended to the base URL and all submits work fine again.

Would be great, if the APEX Dev Team could include the base-URL definition automatically.

AJAX Calls and Interactive Reports

There is still a tiny problem with our friendly URLs. AJAX calls (also Interactive Reports and regular report pagination) don’t work anymore. The AJAX calls are returned with a HTML error code.

To find the reason for that I had to do a code-review of the APEX Javascript AJAX functions and found a Bug in htmldb_Get, which is the underlying function of many AJAX calls in APEX.

Problem here is htmldb_Get doesn’t use the base-URL, it tries to find f?p in the current URL and replaces that with (the AJAX Entrypoint). Our URLs don’t show f?p, so is appended to the end of the current URL, which is obviously wrong.

This Bug still exists in APEX 4.2.4, I hope it will get fixed in APEX 5.0.

There is no easy workaround here. The only option we have is to overload and redefine htmldb_Get, which I did for the demos.

Since this code is very version dependent and over 200 lines of code, I decided not to share it in this blog. If you know your way around javascript you’ll be able to get it from the demo. Otherwise you should keep your hands off.

Again: overwriting htmldb_Get is a workaround which is likely to break with the next APEX Version.


Using friendly URLs is possible today, even in older APEX Versions when using mod_plsql. There are some things you need to take care of in your application, as listed above.

Once you know your way around, it takes a couple hours to turn an existing public application into using human readable URLs.


  1. Rob van Wijk on December 19, 2013

    Thanks for sharing this info in such comprehensive posts. I’ve used Apache rewrite rules, but this looks way better.

  2. Mathieu Meeuwissen on December 20, 2013

    As you stated: it only works for public applications and that is a big limitation, I think.
    Most applications will have some authentication and authorisation.

    How would you solve this matter?
    Is this something the APEX team should try to find a solutions for?

    I hope you can persuade the APEX team to have a look at it, because it is something a lot of developers would like to use.

  3. Peter Raganitsch on December 20, 2013

    I also stated, that it most likely isn’t important to have nice URLs for internal applications.

    Saying that, I can live with this workaround for the time being, but would prefer an integrated solution delivered by APEX itself.

  4. Mathieu Meeuwissen on December 20, 2013

    The real good thing about the nice URLs is that it doesn’t include the application ID.
    Users can bookmark the URL of their internal application(s).
    This means you always have to keep the same application ID.
    When the application is installed under a new application ID, all users have to change their bookmarks.

    It could be avoided by making a portal.
    But still linking between two applications also means that the calling application has to be changed when the called application gets a new application ID.

    The elegance of your solution is that the used application ID’s got be stored in a table.
    That means you only have to maintain it on one place. Much more robust.

  5. Faraz Saleem on April 7, 2014

    Hi Peter,

    I m using your given method to get a nicer url, i have implemented the steps you mentioned above.

    1. Setting all application pages authentication to public.
    2. Setting Cookie Path attributes to /pls/apex/ as mentioned above.
    3. Further i have replaced all targets to URL according to my page name along with cookie path.

    I m getting the following error while navigating to the page.

    Http Status 404- Not Found.
    type Status report
    messageNot Found
    descriptionThe requested resource is not available.
    GlassFish Server Open Source Edition 4.0

    Please help to solve the problem.

    Faraz Saleem

  6. Faraz Saleem on May 13, 2014

    HI Peter,

    I m using Oracle Glassfish server as application server , i want to set the following parameter for it

    PlsqlPathAlias ragtest
    PlsqlPathAliasProcedure rag_url_mapping

    I m not finding the dads.conf in it.
    Please help.


  7. Peter Raganitsch on May 13, 2014

    That’s ok, it means your server is set up correctly.

    The dads.conf exists only for mod_plsql which requires the Oracle Application Server.

    I assume you are using the APEX Listener (Oracle REST Data Services) ? In that case you want to use the RESTful Webservices method.

  8. Faraz Saleem on May 14, 2014

    Hi Peter,

    I have set the following cookie path parameter.

    Cookie Settings:
    My Actual Application URL: MyServer:Port/ords/
    Cookie Path: /ords/
    is it correct?.

    In the second part of your post you created a Procedure URL_DEMO with path parameter, i m not finding this procedure any where in the post for use, i mean where are we using the procedure URL_DEMO.

    Secondly, I m not getting what is hrurl in the link /pls/apex/hrurl/orders mentioned for target, and where are we using the web service in this example.


  9. Faraz Saleem on May 17, 2014

    Hey Peter,

    Below are the steps, i m using for Nicer URL example.

    1. Created a procedure URL_DEMO.

    create or replace PROCEDURE URL_DEMO( p_path IN VARCHAR2)
    v_path := APEX_UTIL.STRING_TO_TABLE(p_path||’/', ‘/’);

    IF UPPER(v_path(1)) = ‘HOME’
    ELSIF UPPER(v_path(1)) = ‘COMPANY’
    HTP.P(‘URL_DEMO called!’);
    HTP.P(‘…path = ‘||p_path);
    END IF;

    2. Created a RESTFul Web service , with the given settings.

    RESTful Service Module
    Name: HRUrl
    Pagination Size:25

    Resource Template
    RESTful Service Module: HRUrl
    URI Template:{path}
    Entity Tag:Secure Hash

    Resource Handler
    URI Template: {path}
    Method :GET
    Source Type:PL/SQL
    Source: BEGIN url_demo(:path); END;

    3. Setting Authentication Scheme and Cookie Path.
    Scheme Type: Application Express Accounts

    Session Cookie Attributes
    Cookie Path:/ords/

    4. Created two public pages.

    5. Created a List for Navigation between pages.
    List Entries:
    1. Home
    Target type:URL
    URL Target:/ords/HRUrl/HOME/
    2. Company
    Target type:URL
    URL Target:/ords/HRUrl/COMPANY/

    6.Created a zero page to display the Navigation List in it.

    Still getting the error 404- Not Found with the given URL http://host:port/ords/HOME/.

    Can you tell me which is the step i m missing.
    looking for your response.