Transition
Import Transition from @waaark/luge, register it with luge.addPlugin('transition', Transition), then call luge.init(). See Getting started for a complete setup.
Brings smooth transition between pages.
Modified clicks (Ctrl, Meta, Shift or Alt), non-primary clicks, download links, and events already cancelled by another handler keep their native behavior. If fetching a destination fails or returns a non-success HTTP status, the browser navigates normally to that destination instead of continuing the transition with invalid content.
Usage
<div class="my-first-page" data-lg-page="my-first-page">
My first page...
</div>
<div class="my-second-page" data-lg-page="my-second-page">
My second page...
</div>
By default, the current page container will be instantly replaced by the new page container, without reloading the page and without transition.
When clicking on an internal link, the transition life cycle starts. The new page is loaded while the page out transition is played. When both are completed, the new page is created in DOM and initiated. And finally the page in transition is played.
luge updates some metas (title, description, keywords and og:image) during transition, as well as <body>class attribute. You can use the pageTransition event (see emitter) to do more changes (like updating the current page link in main navigation).
Use root-relative internal URLs such as /about/, or full URLs on the same origin. Links beginning with #, tel or mailto, links with target="_blank", and links with data-lg-transition="disabled" are ignored. The plugin’s URL checks are string-based: explicitly disable transitions for protocol-relative external URLs (//example.com) and other unusual URL forms rather than relying on origin parsing.
Loader
You can add an animated loader during the page transition. To do so add a data-lg-loader element in your <body>:
Keep the loader outside [data-lg-page] so replacing the page does not remove it.
<div data-lg-loader></div>
By default, the loader will simply get an is-visible class during transition.
You can use one of the built-in animations or create your own one.
Built-in animations
luge comes with a few loader animations:
fadeslide|slide-to-top|slide-to-right|slide-to-bottom|slide-to-left
CSS animation
The loader DOM Element gets a .lg-loader and a.lg-loader—[loader name] CSS classes when initiated. It also gets a .is-visible CSS class during the transition.
You can use these to animate the loader in CSS:
<div data-lg-loader="my-loader"></div>
.lg-loader--my-loader {
opacity: 0;
transition: opacity 0.6s linear;
&.is-visible {
opacity: 1;
}
}
luge will wait for the transitionend event to move to next life cycle event.
JS animation
If you are looking for more complexe animations, you can define transitions in JS:
// Add a callback function
luge.transition.add('out', 'myFirstPage', (page, done) => {
// When [data-lg-page="my-first-page"] goes out
gsap.to(page, { opacity: 0, duration: 0.4, onComplete: done })
})
luge.transition.add('in', 'mySecondPage', (page, done) => {
// When [data-lg-page="my-second-page"] comes in
gsap.to(page, { opacity: 1, duration: 0.4, onComplete: done })
})
// Or attach the function to the element onpageout and onpagein properties
document.querySelector('.my-first-page').onpageout = function (page, done) { gsap.to(page, { opacity: 0, duration: 0.4, onComplete: done }) }
document.querySelector('.my-second-page').onpagein = function (page, done) { gsap.to(page, { opacity: 1, duration: 0.4, onComplete: done }) }
You can define a transition per page or set a default one:
luge.transition.add('in', 'default', (page, done) => {
gsap.to(page, { opacity: 1, duration: 0.4, onComplete: done })
})
The transition callback function gets passed two parameters:
page: the current page DOM element. It contains the old page during the page out transition, and the new one during the page in transition.done(): proceed to the next life cycle event. During the page out transition, call it when you want the new page to be added to the DOM. During the page in transition, call it to launchrevealhooked animations.
Lottie animation
You can use a lottie animation as a transition:
Lottie is not bundled. Set window.lottie to the player before luge.init(); loader animations do not use luge.lottie.deferInit().
<div
data-lg-loader="lottie"
data-lg-loader-out="/path/to/lottie-out-animation.json"></div>
The lottie out animation will be played during the page out transition, to hide the current page.
You can also use a different lottie in animation:
<div
data-lg-loader="lottie"
data-lg-loader-out="/path/to/lottie-out-animation.json"
data-lg-loader-in="/path/to/lottie-in-animation.json"></div>
The lottie in animation will be played after the new page has been added to the DOM.
If you want to use the same animation for page out and page in transition, you can make it play in reverse:
<div
data-lg-loader="lottie"
data-lg-loader-out="/path/to/lottie-out-animation.json"
data-lg-loader-in="reverse"></div>
Full reload
If you want to use a transition but still want to fully reload the page (for instance on e-commerce sites or if new scripts have to be loaded) you can add the data-lg-reload attribute to your page containers, it will play the transition out animation, navigate to the new page and then play the preloader animation if you have one.
In this case, make sure to match the site preloader with the transition out animation in order to keep a consistent animation between pages.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
data-lg-page | String | unset | The page container and optional name used to select page callbacks. Include one in each document. |
data-lg-transition | String | unset | On a link, select a named out callback, or use disabled for normal browser navigation. |
data-lg-reload | Presence | absent | On a page container, force full document navigation after the out animation. Its presence enables it, even with a value of false. |
data-lg-loader | String | unset | The loader animation name. Set it to one of the built-in animations name or create your own one. |
data-lg-loader-out | String | unset | Path to the lottie out animation json file. |
data-lg-loader-in | String | unset | Path to the lottie in animation json file or reverseto use the out animation in reverse. |
Compatibility notes
Only the page container, body classes, title, description, keywords and og:image are updated automatically. New page scripts and stylesheets are not loaded as a general asset pipeline; use the full-reload mode when needed. luge.transition.getOldUrl() and getNewUrl() expose the previous and requested URL, which may be relative. A link-specific out callback takes precedence over the page-named callback, the element’s onpageout, and the default callback.
The plugin also excludes WordPress admin-bar and Cloudflare email-protection links. Custom link-specific out callbacks receive (page, done, trigger); page in callbacks receive (page, done). It fetches complete HTML documents and replaces [data-lg-page]; it is not a client-side router. Failed fetches fall back to document navigation, and modified clicks and downloads retain native behavior. Back/Forward traversal preserves history entries. When requests overlap, the active transition finishes before the latest queued destination starts; intermediate queued requests are discarded. Failure fallback also uses the latest queued destination. Plain slide is an alias of slide-to-top.