Author: | gmrchk |
---|---|
Views Total: | 22 views |
Official Page: | Go to website |
Last Update: | September 25, 2023 |
License: | MIT |
Preview:

Description:
The swup JavaScript library lets you apply custom CSS transitions to pages when switching between them. Supports preload, page cache, and event handlers.
See also:
- CSS3 Based Page Transitions – Animate Transition
- Smooth Page Transitions With JavaScript And PJAX – barba.js
- 10 Best Page Transition Plugins In JavaScript
Table Of Contents:
How to use it:
Install the swup library.
# NPM $ npm install swup --save
Import the swup library.
import Swup from 'swup'
Or directly load the swup file in the document.
<script src="./dist/swup.js"></script> <!-- or from a CDN --> <script src="https://unpkg.com/swup@3"></script>
Initialize the swup library and we’re ready to go.
const swup = new Swup()
Add the CSS ID ‘swup’ to the element you want to animate.
<main id="swup"> Main content here </main>
Add an animation class to the element.
<main id="swup" class="animation-class"> Main content here </main>
Apply your own transition effects to the page.
.animation-class { /* default animation rules */ } html.is-animating .animation-class { /* CSS styles when animating */ } html.is-changing .animation-class { /* CSS styles when changing */ } html.is-leaving .animation-class { /* CSS styles when leaving */ } html.is-rendering .animation-class { /* CSS styles when rendering */ }
All default config options.
const swup = new Swup({ // when this option is enabled, swup disables browser native scroll control (sets scrollRestoration to manual) and takes over this task. // This means that position of scroll on previous page(s) is not preserved (but can be implemented manually based on use case). // Otherwise swup scrolls to top/#element on popstate as it does with normal browsing. animateHistoryBrowsing: false, // animation selector animationSelector: '[class*="transition-"]', // defines link elements that will trigger the transition linkSelector: 'a[href^="' + window.location.origin + '"]:not([data-no-swup]), a[href^="/"]:not([data-no-swup]), a[href^="#"]:not([data-no-swup])', // pass in navigate to treat these links like any other link and perform a regular navigation. linkToSelf: 'scroll', // stores previously loaded contents of the pages in memory cache: true, // default container(s) containers: ['#swup'], // request headers requestHeaders: { 'X-Requested-With': 'swup', Accept: 'text/html, application/xhtml+xml' }, // enable/disable plugins // see below plugins: [], // skips popState handling when using other tools manipulating the browser history skipPopStateHandling: function skipPopStateHandling(event) { return !(event.state && event.state.source === 'swup'); }, // allows ignoring specific visits through a callback ignoreVisit: (href, { el } = {}) => el?.closest('[data-no-swup]'), // provides a way of rewriting URLs before swup will attempt to load them resolveUrl: (url) => { if (url.startsWith('/projects/?')) { return '/projects/'; } return url; } })
Events.
swup.on('animationInDone', () => { // do something }); swup.on('animationInStart', () => { // do something }); swup.on('animationOutDone', () => { // do something }); swup.on('animationOutStart', () => { // do something }); swup.on('animationSkipped', () => { // do something }); swup.on('clickLink', () => { // do something }); swup.on('contentReplaced', () => { // do something }); swup.on('disabled', () => { // do something }); swup.on('enabled', () => { // do something }); swup.on('hoverLink', () => { // do something }); swup.on('openPageInNewTab', () => { // do something }); swup.on('pageLoaded', () => { // do something }); swup.on('pagePreloaded', () => { // do something }); swup.on('pageRetrievedFromCache', () => { // do something }); swup.on('pageView', () => { // do something }); swup.on('popState', () => { // do something }); swup.on('pageLoaded', () => { // do something }); swup.on('samePage', () => { // do something }); swup.on('samePageWithHash', () => { // do something }); swup.on('transitionStart', () => { // do something }); swup.on('transitionEnd', () => { // do something }); swup.on('willReplaceContent', () => { // do something });
Official plugins.
// register plugins const swup = new Swup({ plugins: [new PluginName()] }); // Accessibility Plugin npm install @swup/a11y-plugin import SwupA11yPlugin from '@swup/a11y-plugin'; <script src="./dist/SwupA11yPlugin.js"></script> SwupA11yPlugin({ contentSelector: 'main', headingSelector: 'h1, h2, [role=heading]', announcementTemplate: 'Navigated to: {title}', urlTemplate: 'New page at {url}' }) // Body Class plugin npm install @swup/body-class-plugin import SwupBodyClassPlugin from '@swup/body-class-plugin'; <script src="./dist/SwupBodyClassPlugin.js"></script> SwupBodyClassPlugin({ prefix: '' }) // Custom Payload Plugin npm install @swup/custom-payload-plugin import SwupCustomPayloadPlugin from '@swup/custom-payload-plugin'; <script src="./dist/SwupCustomPayloadPlugin.js"></script> SwupCustomPayloadPlugin({ generatePageObject: (request) => { // receives request object created by swup which contains server response // parse data from request here and prepare it for return return { title, // required - title of page blocks, // required - containers on page in correct order (as marked by [data-swup] attributes in DOM) pageClass, // not requered - class of body element (but might be required by some plugin like Body Class plugin) originalContent, // not required - whole page html content (but might be required by some plugin) }; } }) // Debug plugin npm install @swup/debug-plugin import SwupDebugPlugin from '@swup/debug-plugin'; <script src="./dist/SwupDebugPlugin.js"></script> SwupDebugPlugin({ globalInstance: true }) // Forms plugin (send forms via swup) npm install @swup/forms-plugin import SwupFormsPlugin from '@swup/forms-plugin'; <script src="./dist/SwupFormsPlugin.js"></script> SwupFormsPlugin({ formSelector: 'form[data-swup-form]' }); swup.on('submitForm', e => console.log(e)); // Google Analytics plugin npm install @swup/ga-plugin import SwupGaPlugin from '@swup/ga-plugin'; <script src="./dist/SwupGaPlugin.js"></script> wupGaPlugin({ gaMeasurementId: GA_MEASUREMENT_ID, }) // Gia framework plugin npm install @swup/gia-plugin import SwupGiaPlugin from '@swup/gia-plugin'; <script src="./dist/SwupGiaPlugin.js"></script> SwupGiaPlugin({ components: components, firstLoad: true, log: false, }) // Google Tag Manager Plugin npm install @swup/gtm-plugin import SwupGtmPlugin from '@swup/gtm-plugin'; <script src="./dist/SwupGtmPlugin.js"></script> // Head Plugin (replace the contents of head tag when the content of the page is replaced) npm install @swup/head-plugin import SwupHeadPlugin from '@swup/head-plugin'; <script src="./dist/SwupHeadPlugin.js"></script> SwupHeadPlugin({ persistAssets: true persistTags: true, // persistTags: 'style[data-keep-style]', // persistTags: (tag) => tag.children.length > 1 }) // JS plugin (enable the use of JavaScript for timing and animations) npm install @swup/js-plugin import SwupJsPlugin from '@swup/js-plugin'; <script src="./dist/SwupJsPlugin.js"></script> SwupJsPlugin([ { from: '(.*)', to: '(.*)', in: (next, infos) => { document.querySelector('#swup').style.opacity = 0; gsap.to(document.querySelector('#swup'), { duration: 0.5, opacity: 1, onComplete: next }); }, out: (next, infos) => { document.querySelector('#swup').style.opacity = 1; gsap.to(document.querySelector('#swup'), 0.5, { duration: 0.5, opacity: 0, onComplete: next }); } } ]) // Laravel Livewire Plugin npm install @swup/livewire-plugin import SwupLivewirePlugin from '@swup/livewire-plugin'; <script src="./dist/SwupLivewirePlugin.js"></script> // Matomo Plugin npm install @swup/matomo-plugin import SwupMatomoPlugin from '@swup/matomo-plugin'; <script src="./dist/SwupMatomoPlugin.js"></script> // Preload plugin npm install @swup/preload-plugin import SwupPreloadPlugin from '@swup/preload-plugin'; <script src="https://unpkg.com/@swup/preload-plugin@2"></script> const preloadPromise = swup.preloadPage('/path/to/my/page.html'); swup.preloadPages(); swup.on('pagePreloaded', (page) => console.log('preloaded:' page)); swup.on('hoverLink', (event) => console.log('link hovered:', event)); // Progress Bar Plugin npm install @swup/progress-plugin import SwupProgressPlugin from '@swup/progress-plugin'; <script src="./dist/SwupProgressPlugin.js"></script> SwupProgressPlugin({ className: 'swup-progress-bar', transition: 300, delay: 300, initialValue: 0.25, hideImmediately: true }) // Route Name Plugin npm install @swup/route-name-plugin import SwupRouteNamePlugin from '@swup/route-name-plugin'; <script src="./dist/SwupRouteNamePlugin.js"></script> SwupRouteNamePlugin({ routes: [ { name: 'home', path: '/:lang?' }, { name: 'projects', path: '/:lang/projects' }, { name: 'project', path: '/:lang/project/:slug' }, { name: 'any', path: '(.*)' } ], unknownName: 'unknown', pathToRegexpOptions: {} }) // Scripts Plugin (re-run any scripts in head/body on swups contentReplaced even) npm install @swup/scripts-plugin import SwupScriptsPlugin from '@swup/scripts-plugin'; <script src="./dist/SwupScriptsPlugin.js"></script> SwupScriptsPlugin({ head: true, body: true, optin: false }); // Scroll plugin npm install @swup/scroll-plugin import SwupScrollPlugin from '@swup/scroll-plugin'; <script src="https://unpkg.com/@swup/scroll-plugin@2"></script> SwupScrollPlugin({ doScrollingRightAway: false, animateScroll: { betweenPages: true, samePageWithHash: true, samePage: true }, scrollFriction: 0.3, scrollAcceleration: 0.04, getAnchorElement: null, offset: 0, scrollContainers: `[data-swup-scroll-container]`, shouldResetScrollPosition: htmlAnchorElement => true }) swup.scrollTo(2000, true); swup.on('scrollStart', () => { console.log('Swup started scrolling'); }); swup.on('scrollDone', () => { console.log('Swup finished scrolling'); });
Themes
// register themes const swup = new Swup({ plugins: [new ThemeName()] }); // Fade Theme npm install @swup/fade-theme import SwupFadeTheme from '@swup/fade-theme'; <script src="./dist/SwupFadeTheme.js"></script> SwupFadeTheme({ mainElement: "#swup" }) // Slide Theme npm install @swup/slide-theme import SwupSlideTheme from '@swup/slide-theme'; <script src="./dist/SwupSlideTheme.js"></script> SwupSlideTheme({ mainElement: "#swup", reversed: false }) // Overlay Theme npm install @swup/overlay-theme import SwupOverlayTheme from '@swup/overlay-theme'; <script src="./dist/SwupOverlayTheme.js"></script> SwupOverlayTheme({ color: '#2D2E82', duration: 600, direction: 'to-right', });
Changelog:
v4.4.1 (09/25/2023)
- Fix multiple rapid clicks on links
v4.4.0 (09/19/2023)
- Enable experimental ViewTransition support
- Extend test coverage to all major browsers
- Add request timeout option
v4.3.4 (08/25/2023)
- Add unique id to visit object
v4.3.3 (08/22/2023)
- Restore history index on reload
v4.3.2 (08/20/2023)
- Update history entry on links to the current page
v4.3.1 (08/17/2023)
- Improve scroll restoration on history visits
v4.3.0 (08/16/2023)
- Persist elements across page loads using data-swup-persist
- Add visit.cache key to control cache behavior
- Enforce parameter and return types of hook handlers
v4.2.0 (08/09/2023)
- Add option linkToSelf to control behavior for links to the current page
- Don’t create history records for repeated visits to the current page
- Allow updating visit.to.hash and visit.scroll.target separately
v4.1.0 (07/30/2023)
- Prevent unintentional cache mutation
- Use recommended order for package.json “exports”
- Infer element type from delegate selector
v4.0.1 (07/28/2023)
- Export additional types to allow augmentation from plugins
v4.0.0 (07/26/2023)
- Built-in scroll support
- New hook system for customizing the page load lifecycle
- Visit object for controlling the transition process
- Animation scope: add animation classes to html element or to containers
- Easier customization of official themes
- Allow pruning cache entries
- Hooks replace events: swup.hooks.on()
- Use the visit argument in hooks instead of swup.transition
- Container selectors now only match one single element per selector
- Custom animation attribute renamed to data-swup-animation
- Swup no longer adds data-swup attributes to containers
- Navigation method renamed: swup.navigate()
- Simplified cache API: cache.set()
- Support for custom payload formats was dropped
v3.1.1 (06/24/2023)
- Accept #top as a special scroll target
v3.1.0 (06/13/2023)
- Allow replacing the current history entry
v3.0.8 (06/05/2023)
- Create smaller bundle for modern browsers
- Make warning about missing transitions less strict
v3.0.7 (05/26/2023)
- Update event delegation library
- Fix edge case in detecting transition events
- Improve selection of scroll anchor targets
v3.0.6 (04/07/2023)
- update
v3.0.5 (03/02/2023)
- Ensure correct Referer request header
v3.0.4 (01/30/2023)
- Specify exact types for each type of event handler
- Update package version
v3.0.3 (01/27/2023)
- Use shared browserslist config
v3.0.2 (01/21/2023)
- Make sure ignoreVisit option is called when visiting pages programmatically
v3.0.1 (01/20/2023)
- Fix: remove origin from ignoreVisit parameter
v3.0.0 (01/19/2023)
- Support CSS animations and keyframes
- Allow ignoring visits via callback function
- Export native ESM modules
- Smaller bundle size for modern browsers: 4.5 kB
v2.0.19 (08/24/2022)
- Disable caching of initial page to avoid caching modified DOM
- Gracefully handle missing document title
- Force-reload if next page has no swup containers
- Remove all reliance on global window.swup instance
v2.0.18 (08/10/2022)
- Fixes the buggy behavior when navigating rapidly between pages
v2.0.17 (08/02/2022)
- Gracefully handle missing transitions on container
- Warn about missing container
- Scope transition selector to body
- Normalize cache paths
v2.0.16 (07/01/2022)
- Improve handling of scroll anchors with special characters
v2.0.15 (06/15/2022)
- Update dependencies
v2.0.14 (12/27/2020)
- Bugfix
v2.0.13 (12/07/2020)
- update patch version
v2.0.12 (11/30/2020)
- fix bug where animateHistoryBrowsing option was ignored for OUT animations
v2.0.11 (07/09/2020)
- update version
v2.0.9 (02/26/2020)
- removed destroy of mouseover listener as it was moved to the preload plugin
v2.0.8 (11/01/2019)
- fix problem when ‘<body’ string is present in DOM
v2.0.5 (07/15/2019)
- updated
v2.0.4 (05/31/2019)
- fix wrong uppercase/lowercase letters in imports
v2.0.2 (05/27/2019)
- major update
v1.9.0 (01/07/2019)
- make preloadPage method return Promise
v1.7.18 (01/07/2018)
- fix querySelectorAll issue in form handler and destroy method
v1.7.17 (12/17/2018)
- fix swup getting stuck by errors inside of handlers defined with on method
404…
Fixed. Thank you for reporting.