This checks to see if the request is AJAX rather than Live Preview. If we didn't check for Live Preview, then that feature wouldn't work correctly. You’d only see the entry content and not the whole page in Live Preview.

Note that this needs to be a ternary operator because you can’t have more than one extends in a template, per the Twig documentation.

So, go through and replace all of your default {% extends %} in each of your templates with the updated AJAX version.

Wrapper Element, Used for Animation

The way I handle the AJAX transition animations with Velocity.js is by animating a parent element that wraps all the content on each page. You might find way that works better for your project, but this works flawlessly for me.

…any new <a> tags that are clicked will operate like normal and won't use history.pushState. This applies to most things throughout your JavaScript. You’ll need to make sure that everything still works after being added to the DOM.

Most sites have a consistent header and footer that don't change, and a main content area that does. So we need to use AJAX to replace existing content with new content.

I've opted to use the symantic <main> tag with a .js-main class, which will hold all the content that’s replaced and added:

Now let's make the browser’s Back and Forward buttons work with the AJAX transition. We'll listen for the popstate event, and ensure that we only act upon that event if there's already been a page change:

At this point, the AJAX page transition’s a simple remove and replace. Let's spruce that up by adding some animations. I'll use Velocity.js with the Velocity UI Pack, replacing the contents of the loadPage function: