## Page Transitions

Product: Monogram - Personal Portfolio WordPress Theme
URL: https://hub.jkdevstudio.com/docs/monogram/advanced-features/page-transitions
Updated: 2026-09-10
Summary: Monogram uses Barba.js v2.10.3 to deliver SPA-style page transitions. When a visitor clicks a link, the new page loads in the background while a smooth

Monogram uses **Barba.js v2.10.3** to deliver SPA-style page transitions. When a visitor clicks a link, the new page loads in the background while a smooth fade animation plays - no full browser refresh required. The result is a fast, app-like browsing experience.

## How It Works

1. The visitor clicks a link.
2. The current page fades out while the new page content loads in the background.
3. Once loaded, the new page fades in.
4. All theme features (animations, lazy loading, parallax, Elementor widgets) reinitialize automatically on the new page.

The entire process feels seamless. Visitors stay immersed in your site without the white-flash interruption of a traditional page load.

## Settings

Navigate to **Appearance &gt; Customize &gt; Page Transitions** to configure the feature.

### General Tab

<table> <thead> <tr> <th>Setting</th> <th>Type</th> <th>Default</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Enable Page Transitions</strong></td> <td>Toggle</td> <td>On</td> <td>Master switch for SPA navigation. When disabled, the site uses standard browser navigation.</td> </tr> <tr> <td><strong>Transition Timeout</strong></td> <td>Slider (1000-15000 ms)</td> <td>7000 ms</td> <td>Maximum time Barba waits for a transition to finish before falling back to a normal page load.</td> </tr> </tbody> </table>

### Loader Tab

<table> <thead> <tr> <th>Setting</th> <th>Type</th> <th>Default</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Enable Page Loader</strong></td> <td>Toggle</td> <td>On</td> <td>Show a full-page loader overlay during transitions to mask loading time.</td> </tr> <tr> <td><strong>Loader Fade Duration</strong></td> <td>Slider (0.1-1.5 s)</td> <td>0.4 s</td> <td>Duration of the fade-in and fade-out animation for both the current and incoming page.</td> </tr> </tbody> </table>

### Integrations Tab

<table> <thead> <tr> <th>Setting</th> <th>Type</th> <th>Default</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><strong>Close Boxzilla Popups</strong></td> <td>Toggle</td> <td>On</td> <td>Automatically closes any active Boxzilla popups before navigating to a new page, preventing orphaned modals.</td> </tr> <tr> <td><strong>Reset Scroll Position</strong></td> <td>Toggle</td> <td>On</td> <td>Scrolls to the top of the page after each transition. Works with both native scroll and Smooth Scroll.</td> </tr> <tr> <td><strong>Reinitialize Elementor</strong></td> <td>Toggle</td> <td>On</td> <td>Re-triggers Elementor frontend scripts after each transition so all widgets and effects continue working.</td> </tr> </tbody> </table>

## Requirements for Elementor pages

Page transitions swap the page content in place and carry the new page's Elementor CSS file across with it. Two settings on your site have to leave that file alone, and both sit outside the theme.

- **Elementor CSS print method** must stay on External file, at [[Elementor > Settings > Performance]]. On Internal embedding the CSS is printed as a style block inside the page, and a style block travels with the page it belongs to. The new page then arrives with its own set while the previous set is still in the document, and you see a mixture of the two until a full browser reload.
- **CSS optimization in a caching plugin** must be off for the per-page file. Combine CSS, remove unused CSS, critical CSS, and guest or generic-copy modes merge, rename or strip that file, so there is nothing left to carry across.

The symptom for both is the same: a page that looks broken until you hard refresh it. If you hit that, check these two before anything else, then clear the cache and run **Elementor &gt; Tools &gt; Regenerate CSS &amp; Data**.

<a data-type="kb-embed" href="/knowledge-base/configuration/elementor-settings-checklist">Elementor settings to configure once</a>

## Developer Hooks

If you run third-party scripts (analytics pixels, chat widgets, ad trackers, custom integrations) that need to react to navigation, the theme exposes a small JavaScript event API and a PHP filter so you do not have to fork the theme.

### JavaScript Lifecycle Events

The transition fires five named events in this order:

<table> <thead> <tr> <th>Event</th> <th>When It Fires</th> </tr> </thead> <tbody> <tr> <td><code>beforeLeave</code></td> <td>Old page still in DOM, scripts still bound</td> </tr> <tr> <td><code>afterLeave</code></td> <td>Old page container removed</td> </tr> <tr> <td><code>beforeEnter</code></td> <td>New page injected, runtime classes applied</td> </tr> <tr> <td><code>beforeReinit</code></td> <td>Just before theme features reinitialize on the new page</td> </tr> <tr> <td><code>afterEnter</code></td> <td>Reinit done, page fully ready</td> </tr> </tbody> </table>

A one-shot `ready` event fires once on the very first page load.

Subscribe via the registry API:

```javascript
window.jkdSPA?.on('afterEnter', ({ to, from }) => {
    window.gtag?.('event', 'page_view', { page_path: to.url.path });
    window.fbq?.('track', 'PageView');
});

window.jkdSPA?.on('beforeLeave', () => {
    window.MyChatWidget?.disconnect?.();
});
```

Or via standard `addEventListener` - the same events are dispatched on `window` with a `jkd:spa:` prefix:

```javascript
window.addEventListener('jkd:spa:afterEnter', (e) => {
    console.log('navigated to', e.detail.to.url);
});
```

`jkdSPA.on()` returns an unsubscribe function. Call it to detach the listener.

### Skipping Elementor Reinit on Specific Elements

Some widgets - heavy 3D scenes, embedded video players, anything with persistent state - should not re-run their ready trigger after each transition. Tag the element with the `no-spa-reinit` CSS class in **Elementor &gt; Advanced &gt; CSS Classes**, or register your own opt-out class via PHP:

```php
add_filter('jkd_spa_skip_scripts', function ($classes) {
    $classes[] = 'my-persistent-widget';
    return $classes;
});
```

Any `.elementor-element` matching one of those selectors (or sitting inside one) is skipped during reinit.

## What Is Excluded from SPA Navigation

Certain link types bypass Barba and trigger a normal browser load:

- **Direct image links** - JPG, PNG, GIF, WebP, AVIF, SVG, and other image file URLs
- **Lightbox links** - Elementor lightbox, GLightbox, and WordPress native gallery links
- **WordPress admin bar** - all admin bar links use standard navigation

This ensures that lightboxes, downloads, and admin actions work as expected.

## Safety Timeout

If a transition gets stuck (for example, due to a slow server response), a safety mechanism kicks in after the configured timeout plus 2 seconds. It automatically resets the transition state, hides the loader, and restores normal click behavior so visitors are never left on a frozen page.

## Testing

You can temporarily disable page transitions by adding `?barba_enabled=false` to any URL on your site. This is useful for debugging layout issues or testing how the site behaves without SPA navigation.

If a page renders correctly with that parameter and incorrectly when you click through to it normally, the cause is the CSS setup covered under requirements above, not the page itself.

> **Tip:** Page transitions handle reinitialization of Elementor, AddToAny sharing buttons, Contact Form 7, and the WordPress admin bar automatically. For anything else, hook into the developer events above.