Skip to content

InstantView guide

Steve Hoang edited this page May 5, 2025 · 3 revisions

Overview

The InstantView script enhances website navigation by prefetching the content of links and loading the new page content after a user clicks a link. This approach significantly reduces perceived page load times. However, because InstantView dynamically replaces the DOM (specifically the <body> element) and manages scripts, certain JavaScript features or DOM-dependent functionalities (e.g., image loading, event listeners, or third-party scripts) may not behave as expected after a page transition.

If you encounter issues such as features not working, images not loading, or JavaScript functionality breaking after a page load, this guide will help you troubleshoot and adjust your JavaScript code to work seamlessly with InstantView.

Common Issues and Solutions

1. Images Not Loading After Page Transition

Problem: Images fail to appear or load incorrectly after navigating to a new page using InstantView.

Cause: InstantView replaces the entire <body> element with the prefetched content. If your images rely on JavaScript to load (e.g., lazy-loading scripts) or if image sources are dynamically set, the initialization logic may not re-run after the DOM replacement.

Solution:

  • Reinitialize Lazy-Loading Scripts: If you use a lazy-loading library (e.g., lazysizes), ensure that you reinitialize it after the page transition. You can use the InstantView.on('change', callback) event to detect when a new page has been loaded.
  • Check Image Sources: Verify that image src attributes are correctly set in the prefetched HTML. If images are dynamically loaded, ensure the logic is triggered in the change event.
  • Example:
    InstantView.on('change', function(isInitialLoad) {
      if (!isInitialLoad) {
        // Reinitialize lazy-loading library
        if (typeof window.lazySizes !== 'undefined') {
          window.lazySizes.init();
        }
        // Ensure all images have correct src attributes
        document.querySelectorAll('img').forEach(img => {
          if (img.dataset.src) {
            img.src = img.dataset.src;
          }
        });
      }
    });

2. JavaScript Features Not Working

Problem: Interactive features (e.g., sliders, modals, or form validations) stop functioning after navigating to a new page.

Cause: InstantView re-executes scripts that are not marked with data-instant-track during page transitions, but it does not automatically reattach event listeners or reinitialize third-party libraries. If your JavaScript relies on DOM elements that are replaced, the event listeners or initialized states are lost.

Solution:

  • Use the change Event: Attach a listener to the InstantView.on('change', callback) event to reinitialize your JavaScript features after the DOM is updated.
  • Delegate Event Listeners: Use event delegation to ensure event listeners persist across page transitions. Attach listeners to a parent element (e.g., document) that is not replaced.
  • Example:
    InstantView.on('change', function(isInitialLoad) {
      if (!isInitialLoad) {
        // Reinitialize a slider
        if (typeof window.Slider !== 'undefined') {
          window.Slider.init('.slider');
        }
      }
    });
    
    // Use event delegation for a button click
    document.addEventListener('click', function(event) {
      if (event.target.matches('.my-button')) {
        // Handle button click
        console.log('Button clicked!');
      }
    });

3. Third-Party Scripts Breaking

Problem: Third-party scripts (e.g., analytics, ads, or widgets) fail to load or function correctly after a page transition.

Cause: Many third-party scripts expect to run once during the initial page load and may not handle dynamic DOM replacement. Additionally, scripts marked with data-instant-track are not re-executed, which can prevent tracking or widget initialization.

Solution:

  • Mark Scripts for Restoration: If a third-party script needs to run after every page transition, add the data-instant-restore attribute to the <script> tag. This ensures the script is re-executed.
  • Manually Reinitialize: Use the change event to manually trigger the initialization of third-party scripts.
  • Example:
    <script data-instant-restore src="https://example.com/analytics.js"></script>
    InstantView.on('change', function(isInitialLoad) {
      if (!isInitialLoad) {
        // Reinitialize analytics
        if (typeof window.ga !== 'undefined') {
          window.ga('create', 'UA-XXXXX-Y', 'auto');
          window.ga('send', 'pageview');
        }
      }
    });

4. Event Listeners Not Triggering

Problem: Custom event listeners attached to DOM elements are no longer triggered after a page transition.

Cause: Event listeners attached directly to elements within the <body> are lost when InstantView replaces the DOM.

Solution:

  • Use InstantView.addEvent: Instead of attaching event listeners directly, use InstantView.addEvent(selector, eventType, callback) to delegate events. This ensures listeners are preserved across page transitions.
  • Example:
    InstantView.addEvent('.my-button', 'click', function(event) {
      console.log('Button clicked!');
    });

Debugging Tips

  • Enable Debugging: Add console.log statements in the change, receive, and preload events to trace the execution flow.
    InstantView.on('preload', function() {
      console.log('Preloading started');
    });
    InstantView.on('receive', function(url, body, title) {
      console.log('Received content for:', url);
    });
    InstantView.on('change', function(isInitialLoad) {
      console.log('Page changed, isInitialLoad:', isInitialLoad);
    });
  • Inspect Prefetched Content: Check the prefetched HTML in the receive event to ensure it contains the expected elements and attributes.
  • Verify Script Execution: Ensure scripts are correctly marked with data-instant-restore or data-instant-track as needed.

Best Practices

  • Minimize Direct DOM Manipulation: Avoid directly manipulating the DOM in ways that won't persist after a page transition. Use InstantView events to handle initialization.
  • Test Across Devices: InstantView supports touch and mouse events differently. Test on both desktop and mobile devices to ensure consistent behavior.
  • Use data-instant and data-no-instant: Control which links are handled by InstantView using these attributes. For example, add data-no-instant to links that should trigger a full page reload.
    <a href="/external" data-no-instant>Go to External Page</a>

Reporting Issues

If the above solutions do not resolve your issue, please provide the following details when reporting a problem:

  • A description of the issue (e.g., "Images not loading after clicking a link").
  • The browser and device used (e.g., Chrome 120 on Windows, Safari on iOS).
  • Relevant JavaScript code or third-party libraries in use.
  • Any console errors or logs from the InstantView events.
  • A link to a reproducible example, if possible.

Please feel free to contact me at stevehoang.com with these details for further assistance.