jQuery Accordion: add hash to URL, send Analytics event on open

Recently I had an intense project launching a buddy’s site in Hubspot on a short timeline. Along the way, we created an FAQ page, the Custom Module for this accordion uses jQuery UI Accordion (https://jqueryui.com/accordion/), and so the tricks in general apply far and wide, I think.

The goal:

  • add a URL hash (https://thesitename/faq#thisistheahash) when a question is clicked open, and remove it when closed. Primarily so someone can copy a link to the page with that hash in it
  • make the accordion open if someone comes to the page with the hash in the URL, like if it were emailed to you that way
  • send Google Analytics event data when the question is opened so we can get a sense what questions people are really concerned with.

Just so you know the HTML that gets written out for each accordion item is more or less like this (I simplified it from the actual output in Hubspot):

<div class="accordion" data-url-hash="how-long-does-it-take-to-get-started" role="tablist">
<h4 class="ui-accordion-header" role="tab" id="ui-id-1" >How long does it take to get started?</h4>
<div class="ui-accordion-content" id="ui-id-2"> ... expanded content in here ... </div>

These refer to the code below…

Line 2 is just to keep this action happening only on the FAQ page. Unlike WordPress, in Hubspot I can’t just ask the server what page I’m on (I think).

jQuery UI has an Accordion function,  what was already in use on this Custom Module. It’d be easy to wire up yourself if your theme or site is not already using it. In this case the wrapper <div> has a class ‘accordion’ that’s what activates the expanding/contracting. So I’m just checking for click event on that same div.

In the Custom Module, which is where I define the simple HTML of the accordions, I assigned a value to the data-attribute: ‘data-url-hash’ and have it as lower case, no spaces (dashes instead). When the FAQ accordion is expanded it gets a class ‘ui-accordion-header-active’ (by jQuery UI already) so I just check for that and then using plain javascript write the hash into the URL.

Also, while I’m at it, I defined a Google Analytics event trigger to send information about this FAQ Question. We should see those events in the coming days and I’ll update with a note about it. But I checked that it was firing using a google analytics debugger for Chrome.

Then, I wrote a simple function to clear the hash when the accordion is closed again.

Next,  I had to deal with the case when someone comes to the page and has the hash in the URL already I want to trigger it opening the appropriate accordion. Since I have the data-attribute to work with I run a jQuery filter to find the div.accordion that has that attribute match, and then activate the accordion. In order to get the hash there’s a hand javascript function, but I have to strip out the ‘#’ on the way or it won’t match with my data-attribute.

This is the page where it’s in action: https://www.bigsis.com/faq/ Here is the whole shebang. It’s late so I don’t have time to write the instructions along with the lines themeselves like a better blogger, but maybe I will come back to it if I have time. This all, by the way, is wrapped in a document.ready, and is in a customJS file I have saved in my coded files in Hubspot. It’s key to load the script in the footer, or at least AFTER jQuery, and jQuery UI, AND the accordion instantiation happens.

//get URL and hash for FAQ page
if(window.location.href.indexOf('faq') &gt; -1){

//get clicked or opened FAQ then add a hash to the URL
  var dataUrlHash = $(this).data('url-hash');
  var header = $(this).find('h4');
    window.location.hash = dataUrlHash;
    ga('send', 'event', 'FAQ', 'Open', dataUrlHash);
  } else{

//check if url has a hash, open accordion...
if(window.location.hash) {
  var urlHash = $(location).attr('hash').replace('#', '');
    return $(this).data('url-hash') === urlHash;
  }).accordion("option", "active", 0);

//toggle off the hash when an open accordion is clicked
function removeHash () {
  history.pushState("", document.title, window.location.pathname+ window.location.search);

Leave a Reply

Your email address will not be published. Required fields are marked *