Open Squarespace Search Results in New Window

Add Right-Click Functionality to Squarespace Search Results

Today, I had a client approach me who wanted to add the ability to open search results in a new window on her Squarespace search results page. The basic right-click on a link and choose “Open in new window” functionality wasn’t working for her. The request was odd to me since that functionality is enabled by default on anchor tags in all major browsers. I figured that there might be CSS that is disabling the click functionality on the search results content object and that it would be a quick fix. In other promotions, if you want to make a loans for bad credit no guarantor checkout this link.

After inspecting the code of the Squarespace search results page, I found that it was structured in such a way to not include any anchor tags. Instead, Squarespace is opening search results using Javascript. Here is an example of a search result:

More information about this
keyword in the body of the result

As you can see the only semblance of a link is the url data attribute on .search-result. I checked the settings for the search block and looked for settings site wide, but could not find anything that would allow me to modify this behavior.

Fake it till you make it

The only way I could think to add my client’s requested functionality was to disable the default context menu and create a faux context menu.

There is no Search Results page available for editing to embed the necessary code into so I decided to add it site-wide. Squarespace allows you to inject Javascript and CSS site-wide in Settings -> Advanced -> Code Injection.

First, I created a new div in Javascript for the faux context menu and saved a reference to it for manipulating later:

  var popupHTML = "
Open in new window
"; document.write(popupHTML); var popup = document.querySelector('#new-window-popup');

Then I styled up the faux context menu to make it look similar to a context menu on MacOS (it looks recognizable to Windows users, too, so don’t wig out). Here is the CSS:

#new-window-popup {
  background-color: #efefef;
  border: 1px solid #eee;
  border-radius: 2px;
  box-shadow: 1px 1px 5px rgba(0,0,0,0.5);
  cursor: pointer;
  display: none;
  left: 0;
  padding: 0.2em 0.5em;
  position: absolute;
  top: 0;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
  z-index: 10000;
}
  
#new-window-popup:hover {
  background-color: #eee;
}

After I got the faux context menu looking good, I disabled the default context menu when right-clicking in a .search-result. To do this, I first needed to create a little function that would travel up the DOM tree for me and search for a specific class. I found this awesome snippet on Stack Overflow to do just that:

function findAncestor (el, cls) {
  while ((el = el.parentElement) && !el.classList.contains(cls));
  return el;
}

Disable default functionality

I added a contextmenu event listener on the document to detect the default context menu trigger and prevent it from displaying:

document.addEventListener('contextmenu', function(e) {
  var searchResult = findAncestor(e.target, 'search-result'); // a search result item
  var searchPage = findAncestor(e.target, 'sqs-search-page'); // to make sure we were in a search page
  var searchPreview = findAncestor(e.target, 'sqs-search-preview-ui'); // to make sure we were NOT in a search box preview
  if ((searchResult != null 
    && searchPage != null 
    && searchPreview == null) || e.target.id == 'new-window-popup') {
    e.preventDefault();
  }
}, false);

Coding up something new

With the default context menu hidden, I then added a click event listener to the document for detecting mouse clicks. Depending on the button clicked, I can show and hide the faux context menu and then attach an appropriate event listener to trigger a new window:

document.addEventListener('mousedown', function(e) {
  // Right click
  if (e.button === 2) {
    var searchResult = findAncestor(e.target, 'search-result');
    var searchPage = findAncestor(e.target, 'sqs-search-page');
    var searchPreview = findAncestor(e.target, 'sqs-search-preview-ui');

    if (searchResult != null 
      && searchPage != null 
      && searchPreview == null) {

      // Display the context menu
      popup.style.display = 'block';

      // Position the menu
      popup.style.left = e.pageX+'px';
      popup.style.top = e.pageY+'px';

      // Get the url and add the event listener to the faux context menu
      var url = searchResult.dataset.url;
      addOpenNewWindowEvent(popup, url);

    }

  // Any other click dismiss the menu
  } else {

    // After a second, hide the faux context menu
    // if you don't wait to hide the menu the event
    // trigger on the faux context menu can't trigger
    setTimeout(function(){
      popup.style.display = 'none';
    }, 1000);

  }
});

function addOpenNewWindowEvent(target, url) {
  target.addEventListener('click', function() {
    window.open(url);
    target.removeEventListener('click', arguments.callee, false);
  });
}

And there you have it. Why Squarespace decided to build their search results without anchor tags is beyond me. However, my task on this project wasn’t to complain about it, it was to find a solution to it.

I hope other developers who work with Squarespace find this useful.

Leave a Comment

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