# AJAX Transitions

The template is powered by seamless AJAX transitions thanks to Barba.js (opens new window) plugin.

⚠️ AJAX transitions work only with a web-server

You need to use any web-server to make AJAX transitions work. If you open the template files locally via the filesystem you may get the browser console error like this one:

"Access to XMLHttpRequest at '...' from origin 
'null' has been blocked by CORS policy:
Cross origin requests are only supported
for protocol schemes: http, data, chrome,
chrome-extension, https."

# Markup

<body>
  <div data-barba="wrapper">
    ...
    <div
      data-barba="container"
      class="js-smooth-scroll"
      id="page-wrapper"
    >
      <main class="page-wrapper__content">
        ...
      </main>
    </div>
    ...
  </div>
</body>

  • Everything outside Barba container with data-barba="container" attribute will remain unchanged when navigating the website. This could be a page header and a page scripts.
  • To turn off AJAX transitions, remove attribute data-barba="wrapper" from the div container. Or simply unwrap everything from this container since it doesn't create any styling in the document.

# Excluding Rules

If you don't want the specific links to trigger the AJAX transitions, here are the options.

Add data-barba-prevent attribute for the link you want to act as a normal link:

<a
  href="/downloads/somefile.zip"
  data-barba-prevent="self"
>
  Download File
</a>

Add an outer wrapper with data-barba-prevent="all" attribute for all the links you want to act as normal links:

<div data-barba-prevent="all">
  <a href="/downloads/somefile1.zip">Download File 1</a>
  <a href="/downloads/somefile2.zip">Download File 2</a>
  <a href="/downloads/somefile3.zip">Download File 3</a>
</div>
# Option 3. Add jQuery selectors to the prevent rules

This option is useful if you don't want to change the HTML markup.

<a href="#" class="my-link-class">Link 1</a>
<a href="#" id="my-link-id">Link 2</a>

Find the following template options object in 📄 js/components.js file and specify the custom rules:

...
/**
 * Default Theme Options
 * Used to prevent errors if there is
 * no data provided from backend
 */
if (typeof window.theme === 'undefined') {
  window.theme = {
    ...
    ajax: {
      enabled: true,
      preventRules: '.my-link-class, #my-link-id' // jQuery selectors of the elements to exclude them from AJAX transitions
      updateNodesAttributes: '',
      updateScriptNodes: '',
      loadMissingScripts: true,
      loadMissingStyles: true,
      evalInlineContainerScripts: false
    },
    ...
  }
}
...

# 3rd-party Scripts Compatibility

When extending the template functionality with a JavaScript plugin that’s not included to the package, you may run into an issue. Your plugin may work good after the initial site load. But when it comes to any AJAX transition it doesn’t initialize again. This is an expected behavior due to the nature of AJAX technology.

All the 3rd-party scripts you need to re-init manually each time an AJAX transition occurs. You can do this by placing the initialization code of your plugin inside initComponents() function wrapper in 📄 js/components.js file:

/**
 * Init Template Components
 * You can init your custom scripts here
 * in that function
 */
function initComponents({
	scope = window.$document,
	container = window.$pageWrapper,
	scrollToHashElement = true
}) {

  ...
  
  //
  // your custom plugins init here
  //
}

# Ad Trackers Compatibility

Some of the popular tracking scripts are already AJAX-compatible with Kinsey template. It means that you don’t have to write any additional functions to make them work flawlessly. Those include:

  • Google Analytics
  • Facebook Pixel
  • Yandex.Metrika

If you need to fine tune those ad tracking update functions, please take a look at PJAXUpdateTrackers() function in js/components.js file.

function PJAXUpdateTrackers() {

  updateGA();
  updateFBPixel();
  updateYaMetrika();

  /**
   * Google Analytics
   */
  function updateGA() {
    if (typeof gtag === 'function' && typeof window.gaData === 'object' && Object.keys(window.gaData)[0] !== 'undefined') {
      const
        trackingID = Object.keys(window.gaData)[0],
        pageRelativePath = (window.location.href).replace(window.location.origin, '');

      gtag('js', new Date());
      gtag('config', trackingID, {
        'page_title': document.title,
        'page_path': pageRelativePath
      });
    }
  }

  /**
   * Facebook Pixel
   */
  function updateFBPixel() {
    if (typeof fbq === 'function') {
      fbq('track', 'PageView');
    }
  }

  /**
   * Yandex Metrika
   */
  function updateYaMetrika() {
    if (typeof ym === 'function') {
      const trackingID = getYmTrackingNumber();

      ym(trackingID, 'hit', window.location.href, {
        title: document.title
      });
    }
  }

  function getYmTrackingNumber() {
    if (typeof window.Ya !== 'undefined' && typeof window.Ya.Metrika2) {
      return window.Ya.Metrika2.counters()[0].id || null;
    }

    if (typeof window.Ya !== 'undefined' && typeof window.Ya.Metrika) {
      return window.Ya.Metrika.counters()[0].id || null;
    }

    return null;
  }
}