Part of building great applications is not only making them beautiful, but also easy to use. Help in the form of tooltips and on page instructions isn’t always enough. We have recently started working with Zendesk and are slowly building up a great knowledge base. Our aim was to serve our articles directly to our users within our application, in a meaningful way. We therefore embarked on an Oracle APEX and Zendesk integration.


Zendesk Help within APEX

We are very happy with the results, and wanted to share so you can do the same! Here’s how.

1. Widget Settings in Zendesk

i. Log in to your Zendesk account and click on the Settings icon. This will allow you to configure your widget as below, in the customization tab

Make sure you have enabled Help Center and Contextual Help

ii. Next, go to the Set Up tab and grab your widget snippet. This piece of code will contain your secret key.

<script id="ze-snippet" src=""> </script>
<!-- End of xxxxx Zendesk Widget script -->

2. Database objects needed for our Oracle APEX and Zendesk integration

We wanted to be quite specific with our context sensitive help, so we decided to use a simple table. It contains primarily APP_NAME (Alias), PAGE_ID, and SEARCH_STR. This enables us to simply build up a list of very specific keywords or search terms per page.

A package (ZEN_DESK_PKG) then queries this table and prints the appropriate HTML region necessary for the widget.

Our package looks something like this. Please note that we have simplified it here, as we had slightly different requirements. However this should suffice for illustrations purposes!

create or replace PACKAGE BODY "ZEN_DESK" AS

  procedure print_help_html(p_app_id number, p_page_id number, p_user_id number) AS
    v_html varchar2(32000) := q'!
  <!-- Start of Zendesk Widget script -->
  <script id="ze-snippet" src=""></script>
  <script type="text/javascript">
  zE(function() {
      zE.setHelpCenterSuggestions({search: "#SEARCH_STRING#"});  -- when this value is set, the widget will suggest appropriate articles
        name: "#NAME#",  -- we know who our users are, so let's pre-populate
        email: "#EMAIL#",
        organization: ""
  <!-- End of Zendesk Widget script -->
    v_user_r our_user_table%rowtype;
    v_search_str varchar2(4000);

    select *
      into v_user_r
      from our_user_table
     where id = p_user_id;

    v_html := replace(v_html, '#NAME#', v_user_r.first_name||' '||v_user_r.last_name);  -- this is to identify our user and prepopulate the contact info
    v_html := replace(v_html, '#EMAIL#', v_user_r.parent_email);

/* using the app_id and page_id, look up in the table and see if we have any entries with pre-set search terms  */

    for i in(
      select zd.*
         from our_zen_desk_info_table zd, our_apps_table a
         where a.app_alias = p_app_id
         and a.app_name = zd.app_name
         and zd.page_id = p_page_id) loop

        v_search_str := v_search_str || i.search_str || ' ';
    end loop;

    v_html := replace(v_html, '#SEARCH_STRING#', trim(v_search_str));
  END print_help_html;



3. Global Page – APEX – Zendesk region

We wanted help to be available throughout our application, so we included our Zendesk Widget call on Page 0 (Global Page).

The zE.setHelpCenterSuggestions function allows us to pass in a search string dynamically to the widget, and our goal was to make this as relevant as possible.

For example, when a user is on the ‘Manage Users’ page, we knew which articles we wanted to suggest, as below:

Notice that there is a list of suggested articles, before the user has even entered a query. This uses the Context Sensitive help feature we configured above.

We added a PL/SQL Dynamic Content region on Page 0, as below:


ZEN_DESK.print_help_html(p_app_id => :app_id, p_page_id => :app_page_id, p_user_id => :p_user_id);


And that’s all there is to it! It was extremely simply for us to complete our APEX and Zendesk integration. We love being able to control the suggested articles.

There are so many ways you could do this differently, of course. You could pass in the Page Name if they contain relevant search terms, or alias, or simply page number if your have used good logic in your page numbering (example: page 1-99: Orders, 100 – 199: Products), Page Group…

We really wanted to narrow down the results and control exactly what appeared on every page, so we went quite granular here, but you might not need to go that far.

Please note that if a page has no entry in our table, the widget simply appears with no suggested articles, and the user can enter a search term to search our database themselves:

This was a super simple integration as you can see, and we are definitely finding it has reduced our support emails as users can self-serve from right within the app. What we particularly love is that they don’t even have to leave our app to read the article. When they click on it in the widget, it appears directly there, without the loss of context:

4. Other ways to help your users

For a different twist on Oracle APEX Help, you might be interested Anton Nielsen’s recent post about how to create a Consolidated Help Page in your app.

Daniel Hochleitner has a pretty cool plugin you can use if you’d like to give your users a quick site tour using tooltips.

Also, don’t underestimate the importance of APEX Item level help and Page Level Help. Will the users bother clicking on those little icons? Not convinced, but it can still decrease your support time if all you have to answer is: click on the question mark icon and you’ll get your answer :-)

Thoughts or comments? We’d love to hear from you! Here’s to building fast and beautiful applications, fellow APEXers!