Open-in-new-tab issues in Replay

I’ve crawled a site that makes ubiquitous use of target=“_blank” for lots of internal links. There are 1200+ local links in the live project that are set to open in a new window/tab, and that action is being carried over to the web archive, meaning that when I click on certain things in the replay, it’s opening a whole new replay tab in my browser for the linked content. Then, as expected, I can’t use the new window’s back button to get back where I was. It’s not a huge deal, but I do wonder if there is a way to script out this action so links open in the same replay window?

I don’t know of a way to change this in ReplayWebPage. I think an argument could be made that keeping that behavior is most faithful to the original? If you are in control of the site in question I guess you could turn it off there prior to archiving? Alternatively it might be possible to inject some JavaScript to remove the target properties after loading? But I’m not sure how to inject JavaScript into the replayed content.

Hi, I have multiple other issues when browsing archived content, and use content injection to ‘fix’ these (in the same way flash content is supported, by running Javascript on the replayed page after load).

As we’re using Kubernetes, a Docker image supporting injection helped. You could do something like the following (in a mounted inject.js), here all links with Javascript handlers are reset to become ‘regular’ links.

(function () {
  // disable click handlers of links, so we can follow links server-side instead of client-side
  // probably will need some tweaking on some sites!
  function disable_js_links({ dynamic = false, removeAttrs = [] }) {
    function removeHandlers(node) {
      const clone = node.cloneNode(true);
      (removeAttrs || []).forEach((attr) => {
        clone.removeAttribute(attr);
      });
      node.replaceWith(clone);
    }

    window.addEventListener('DOMContentLoaded', (event) => {
      console.debug('[inject.js] Removing event handlers from <a> elements...');
      // optionally do this on newly added elements
      if (dynamic) {
        const observer = new MutationObserver((mutationList, observer) => {
          for (mutation in mutationList) {
            if (mutation.type === 'childList') {
	      mutation.addedNodes.forEach(removeHandlers);
            }
          }
        });
        observer.observe(document.body, { childList: true, subtree: true });
      }
      // Remove event handlers from all existing a elements
      document.querySelectorAll('a').forEach(removeHandlers);
    });
  }
  
  // Site-specific tweaks based on hostname
  const re = new RegExp('^.+https?:/+(www\.)?([^/?]+)', 'i');
  const match = document.location.pathname.match(re);
  const domain = match && match[2];
  console.log('[inject.js] Activating tweaks for', domain);
  switch(domain) {
    case 'example.com':
      disable_js_links({});
      break;
    default:
      console.log('[inject.js] No domain-specific Javascript injections for', domain);
  }
})();

You could do something similar for your case, removing all target attributes on all links (and update the case statement to match the relevant websites).
And actually, you could use disable_js_links({ removeAttrs: ['target'] }) instead of disable_js_links({}) to obtain your desired behaviour.

Thanks for sharing the snippet. Perhaps it might make sense to enable something like this as an option, but of course it break certain sites altogether.

We’ve attempted to fix this for simple cases target="_blank" in this PR:

Perhaps its worth revisiting this to see if there’s something else that could be done.

Also, if deep-linking is enabled, it can still work even with opening a new page in a new tab.

@jmulliken it looks like this was the project, right? https://archive.supdigital.org/layered-lives.html
It seems that the links that open in a new tab do work, because they redirect back to top-level page with new hashtag (links from clicking on the map)

That’s correct, Ilya. The links within the pop-ups generated by clicking on map dots do open in a new tab. And the old tab remains open and perfectly usable. And Ed is right that this behavior is faithful to the original work. If anything, it makes me consider adding to SUP’s development guidelines to discourage target=“blank” for linking to internal content in most cases. This is another example of how working through archiving can inform best-practices for development.

2 Likes