Browse AjaxPress docs

Make your theme or plugin AjaxPress-friendly

On this page

Good news first: code written for ordinary WordPress pages already works with AjaxPress. Each page loads as a complete document, inside a frame, with all of its scripts. DOMContentLoaded, load and jQuery’s ready fire on every page. There’s nothing to re-initialise.

This checklist covers the few patterns that do need care. For how the frame and the top window fit together, read Where your code runs first.

Don’t break out of the frame

AjaxPress shows your pages inside a frame on the same site. These all force a full page load, or a blank page:

  • Frame-busting scripts, such as if (top !== self) top.location = self.location;. Remove them, or check the origin: window.top.location.origin !== location.origin.
  • X-Frame-Options: DENY or frame-ancestors 'none' headers. Use SAMEORIGIN and 'self'. See Security plugins and headers.
  • target="_top" on ordinary links and forms. Only use it where you really want a full page load.
  • Navigating with window.top.location instead of window.location. For an ordinary redirect, set window.location.href; AjaxPress picks the new page up.

Prefetch loads a page when its link is hovered. A link that changes something when loaded (log out, add to cart, delete, unsubscribe, mark as read) can run before the visitor clicks.

  • Use a form with method="post", or a button handled by your script, for actions.
  • If it has to be a link, add a confirmation step, or give site owners the pattern to add to Exclude Links. From your own code, add it with the bypassPatterns filter:
(window.ajaxpressModules = window.ajaxpressModules || []).push((api) => {
  api.addFilter('bypassPatterns', (patterns) => [...patterns, 'action=my_plugin_logout']);
});

Handle your own form submissions properly

If your script submits a form over ajax, call event.preventDefault() in its submit handler. AjaxPress checks defaultPrevented, sees the form is taken care of, and stays out, so the form isn’t submitted twice. AjaxPress’s own listener runs after page-level handlers, including jQuery delegated ones.

If your handler is attached late (after the visitor could already submit), or doesn’t call preventDefault(), put data-ajaxpress-ignore-submit on the form. See Forms.

Persistent elements

If your plugin shows a player (or anything else that should survive page changes):

  • Print it on every page, from a site-wide hook such as wp_footer, not inside post content.
  • Mark the outer wrapper: data-ajaxpress-persist.
  • Give it a fixed identity: data-persist-key="my-plugin-player". Never put per-page values (timestamps, cache busters) in its id or its media src.
  • Position it yourself with position: fixed. Once lifted, it leaves its parent, and parent-scoped CSS stops applying.

See Keep audio or video playing across pages.

Code that must follow the visitor across pages

Almost nothing needs this. If yours does (a player’s state, a chat session), run it once, in the top window:

if (window.self === window.top) {
  document.addEventListener('ajaxpress:ready', (e) => {
    // e.detail.url is the page now on screen.
  });
}

Don’t add listeners to window.top.document from inside the page: every page would add another. See the events reference.

Analytics

Your page view code runs on every page, so page views are already counted. Don’t send extra page views from ajaxpress:ready or the ajaxpress_page_view dataLayer event, or every page is counted twice.

Detect AjaxPress

// Is AjaxPress active on this page?
const hasAjaxPress = typeof window.AjaxPress !== 'undefined';

// Is this page shown inside AjaxPress's frame?
const inAjaxPressFrame = window.self !== window.top &&
  !!window.top.document.getElementById('ajaxpress-persist');

Test checklist

  1. Click through five or more pages, including your plugin’s pages.
  2. Submit each of your forms once. Check for exactly one submission.
  3. Press Back and Forward a few times.
  4. With AjaxPress Pro and prefetch on, hover over your plugin’s links. Nothing should change until you click.
  5. Check the browser console for errors on each page.
  6. Test logged in and logged out, and on a phone.

Found something AjaxPress should handle better? Email [email protected]. We’re happy to work with plugin authors.