Complete, flexible, extensible and easy to use page transition library for your static web.

Overview

We're looking for maintainers!


swup

Complete, flexible, extensible and easy to use page transition library for your static web.

npm version Gzip Size License npm downloads CircleCI

Here's what's new in v2. Check changelog for recent changes, see all swup repositories to discover more, or checkout the discussions.

If you're having trouble implementing swup, checkout Common Issues, Closed Issues or open a new one.

Become a backer or sponsor on Open Collective or support swup through GitHub sponsors.

Comments
  • Allow ignoring links from function callback

    Allow ignoring links from function callback

    Description

    Currently, the only official way of ignoring links is by appending the link selector option. This can get very complex very easily and it's not possible to do more advanced checks like e.g. ignoring all links inside a specific container. (The unofficial way would be listening to and preventing the click event in the capture phase).

    The proposed change will split the check into to phases: select all links by selector, then filter via user-supplied callback.

    This feature has been requested a few times and would be something I'd find very useful in my own projects.

    Advantages

    • Makes the selector much simpler
    • Allows ignoring a whole container element with the data-no-swup attribute, not just every link individually
    • We can add certain checks that will always skip swup, like target=_blank or the download attr on links
    • Plugins can reuse some of the logic for other visit "triggers", e.g. forms plugin

    Checks

    • [x] The PR is submitted to the ~~master~~next branch
    • [x] The code was linted before pushing (npm run lint)
    • [x] All tests are passing (npm run test)
    • [x] New or updated tests are included
    • [x] The documentation was updated as required

    Additional information

    • This is a breaking change since we're ignoring a[download] elements. Hence submitting to the next branch.

    Questions

    • How would this tie in with #508 ?
    opened by daun 20
  • Support CSS keyframes and multiple transition durations

    Support CSS keyframes and multiple transition durations

    Feature addition to allow multiple transition durations as well as animation keyframes.

    Things that currently don't work

    • Combining multiple transitions with different durations and having both finish: swup will only wait for the first transition to finish before replacing the content
    • Using animation keyframes for page transitions: swup only supports the transition property

    What this PR does to make those things work

    • Wait for all transitions to finish before replacing the content
    • Detect and work with CSS animations as well, choosing whichever is longest

    Prior art

    Most of the new behavior is lifted straight from Vue's transitions module.
    It's working really well so far on a lot of production sites of mine.

    Questions

    • Is there any argument to be made for NOT waiting for all transitions to finish?
    • Should we prefer transitions to animations? The PR currently defaults to whichever has the longest duration in case both are defined.

    Notes

    • Added tests for simple and complex transitions as well as animation keyframes
    • Looks somewhat complex, but will increase bundle size by barely 0.05KB
    opened by daun 19
  • Handle rapid navigation

    Handle rapid navigation

    Fixes the bug described in #187 .

    This attempt addresses the described bug by doing two things:

    1. Don't execute renderPage if page.url doesn't match getCurrentUrl():
    const isCurrentPage = this.getCurrentUrl() === page.url;
    if( !isCurrentPage ) return;
    
    1. Remove all swup-related html-classes on popstate, if animateHistoryBrowsing is false:
    if( !this.options.animateHistoryBrowsing ) {
      document.documentElement.classList.remove('is-animating');
      cleanupAnimationClasses();
    }
    

    I tried to run cypress on this, but I can't get it to work / I have never used it. Manual testing looked fine, though.

    opened by hirasso 19
  • New global option: `resolvePath`

    New global option: `resolvePath`

    Replaces #508

    Adds a new global option to swup, that allows to run a callback for how swup should resolve a path.

    What is the problem?

    Right now, to be able to leave and re-enter control over the browser URL/state by swup, three steps are necessary:

    • Use skipPopStateHandling with custom logic
    • Manually ignore links with one of the given options (linkSelector, stopPropagation() during the capture phase,...)
    • Manually adjust the cache URLs so that back- and forward navigation doesn't need additional server requests

    While this kind of behavior is already possible to achieve with the currently available swup API, it adds a lot of boilerplate to each new site that wants to have this. Also, the current cache implementation is less than ideal for that kind of scenario right now. It will either fill itself up with unnecessary duplicates of the same page or have cache misses for pages that were previously already loaded from the server.

    Proposed solution

    All three of the above topics basically boil down to always the same question: Should various paths actually be resolved to just one by swup?

    • on popState: Is the resolved version of the new browser URL the same as the previous one? > ignore
    • on clickLink: Is the resolved href of the link the same as the current browser URL? > ignore
    • Accordingly to swup ignoring the above events if paths resolve to the same one, the cache can also just keep one copy for all URLs that resolve to the same one.

    Demo & Test Site

    I have set-up a test site here: https://test.rassohilber.com/swup-resolve-path/test/

    On that site, the whole filter logic is done by a custom component that doesn't want swup to interfere. It does everything from updating the URL to rendering the state. Navigation away from the list to one of the character detail pages or to the "about"-page and back again is being handled by swup again. To make it more obvious that there is no page load between filters, I added a staggered animation to the items that only runs if the page is being fully rendered (initially and by swup).

    Code Example

    const swup = new Swup({
      resolvePath: path => {
        // resolve every URL that contains '/?=filter=xyz' to '/'
        return path.replace(/\/\?filter=.+/, '/');
      }
    })
    

    Checks

    • [x] The code was linted before pushing
    • [x] All tests are passing
    • [x] New or updated tests are included
    • [ ] The documentation was updated as required
    • [ ] Make sure that restoring scroll positions in ScrollPlugin also uses the resolved path
    enhancement 
    opened by hirasso 18
  • Make `ignoreLink` accessible for plugins

    Make `ignoreLink` accessible for plugins

    • move all checks out of linkClickHandler and in a dedicated method ignoreLink
    • move the el.origin check from the option inside this method

    Makes it possible for plugins to call swup.ignoreLink(el)

    Related: #551

    opened by hirasso 17
  • Create playground

    Create playground

    Set up a simple test site with basic setup and transitions for people to try out swup.

    Options:

    • Repo with static files and npx serve
    • Microsite on docs domain
    • REPL on Glitch, CodeSandbox, etc.
    opened by daun 17
  • How to integrate Swup in Wordpress?

    How to integrate Swup in Wordpress?

    Guys, I need help integrating swup to my wordpress site. I try everything, put <main id="swup" class="transition-fade"> around content in my index.php, page.php, single.php, archive.php, search.php..

    Create function in my function.php

     function pro_adding_scripts() {
    	 wp_register_script('swup-pro-script', get_template_directory_uri() . '/swup.min.js', array('jquery'), '1.2', false);
    	 wp_enqueue_script( 'swup-pro-script');
    	 
    	 wp_register_script('swup-pro-script2', get_template_directory_uri() . '/script.js', array('jquery'), '1.2', false);
    	 wp_enqueue_script( 'swup-pro-script2');
    }
    add_action( 'wp_enqueue_scripts', 'pro_adding_scripts' ); 
    

    import script in header.php

    <script src="/swup.min.js"></script>
    <script src="/script.js"></script>
    

    Use this in my script.js file:

    import Swup from 'swup';
    
    const swup = new Swup({
     		LINK_SELECTOR: `a[href*="${domain}"]:not([data-no-swup]), a[href^="/"]:not([data-no-swup]), a[href^="#"]:not([data-no-swup]), a[xlink\\:href]`,
     	});
    

    and add this css:

    .transition-fade {
      transition: 0.4s;
      opacity: 1;
    }
    
    html.is-animating .transition-fade {
      opacity: 0;
    }
    

    Nothing happened... when press any link page just reloads normal. I'm not sure what I doing wrong.

    opened by ANONIMNIQ 17
  • How to use Swup with VueJs

    How to use Swup with VueJs

    Hi guys,

    which is the best way to use Swup page transition with VueJs components?

    I need to use Swup because the project is based on CMS and I need to manage dynamic routes. So, I tried to use the Vue method $destroy and re-mount the same instance but I've a common navbar components (the same for all pages) that after first page transition stop to be reactive.

    Any ideas?

    opened by lionettiluca 16
  • Varying elements replaced

    Varying elements replaced

    Hello, awesome library. am loving it so far. I'm having difficulty figuring out how to replace different elements for different pageLoads, or indeed if this is possible. swup initialised with elements: ['#main__wrap','#hdr-crt-lnk']

    works fine for all links.

    however, i do a custom pageLoad for form submission where I set elements: ['#contact--form']

    As I only want to replace the form on submission. all works as expected apart from the new form content is loaded into #main_wrap instead of #contact--form.

    I hope this makes sense. I'll continue you to investigate (read fiddle & play) to see if i can figure it out, but any assistance would be greatly appreciated.

    thanks in advance cheers gwil

    opened by richgwil 16
  • Option to not skip animations when going back in history

    Option to not skip animations when going back in history

    The default swup behaviour is skipping animations when you go back in history. I tried to animate the pages by assigning to options.skipPopStateHandling a function which always returns true (prevents the default behaviour) and loads the page by loadPage() so it does animate. But this also creates a new entry in browser history and when you now try to go back it loads the same page over and over. So the only way would be altering the Swup files. Thank you for taking this into consideration

    help wanted 
    opened by OSDVF 16
  • Delay caching first page until after DOM load event

    Delay caching first page until after DOM load event

    When a first page-load has <style> tags in a container used by Swup, it will not add them to the cache. Navigating back will result in the page not having the <style> tags that it initially existed.

    This issue does not present itself with subsequent page-loads, loaded by mouse-over, for example. It that case, the tags get added to the cache properly.

    Workaround

    For now, you can turn off the cache:

    const options = {
      cache: true
    }
    

    This isn't ideal (the caching Swup does is the reason I'm using it, and it rocks when it works), but this will prevent any lost styles. The issue is especially pungent on Wordpress 5.9+ sites that insert dynamic <style> blocks.

    bug 
    opened by mevanloon 15
  • Javascript wait for css animations to finish

    Javascript wait for css animations to finish

    Discussed in https://github.com/swup/swup/discussions/557

    Originally posted by kaspost December 27, 2022 Basically, I'm coding an app with swup that primarily consists of transitions done through pure css. However, there are a few cases where some css properties need to be calculated through javascript before they are animated in. To solve this, my approach was to add the swup js plugin and use it like this:

    new SwupJsPlugin([ { from: '(.*)', to: '(.*)', in: prepareTransitions, out: prepareTransitions, }, ])

    And the prepareTransitions function basically looks like this:

    const prepareTransitions = next => { calcAndSetCssProperties(); next(); }

    The problem here becomes that swup doesn't wait for the animations to finish when switching between pages. This obviously has to do with the fact that next is invoked instantly after calcAndSetCssProperties. In order to solve this, is there a swup method that I can utilize to wait for all animations to finish and then invoke the next function?

    opened by kaspost 1
  • Introduce peerDependencies for plugins

    Introduce peerDependencies for plugins

    For swup@3 we'll need to introduce proper peerDependencies for all plugins, when we migrate them to use swup's updated API functions:

    https://nodejs.org/es/blog/npm/peer-dependencies/

    opened by hirasso 0
  • Switch to native URL API

    Switch to native URL API

    • [x] Use native URL objects for parsing URL parts
    • [x] Create a helper to instantiate URLs from HTML and SVG links
    • [ ] Find a better solution than the custom address getter

    Related to #551

    opened by daun 15
  • Handle non-http protocols with new `ignoreLinks` option

    Handle non-http protocols with new `ignoreLinks` option

    The upcoming implementation of ignoreLinks has one flaw: it doesn't ignore links with protocols like tel: or mailto:. We'll need to add that check before the release and add tests as well.

    Edit: Actually, it does. We're checking for link.origin and comparing to location.origin, that includes the protocol. Still, we should make sure it's either http or https in any case.

    new URL(document.URL, document.baseURI)
    new URL(window.location.pathname, document.baseURI)
    

    Some questions to ask:

    • Should we move the origin check into a separate function that cannot be overriden? I'm actually not sure what the advantage is of allowing cross-origin requests
    • Should we switch to the native URL object instead of swup's Link class? Makes more sense to me
    • Maybe look for inspiration in Turbo's URL module
    opened by daun 2
  • Optimize CI setup

    Optimize CI setup

    Ongoing effort to switch all CI checks to GitHub actions.

    Goals

    • Avoid CircleCI usage limits (test runs are hidden when free quota is met)
    • Speed up test runs (GitHub actions looks to be 50-70% faster than CircleCI)

    Tasks

    • [x] Create GitHub action for E2E tests with Cypress (see workflow runs)
    • [x] Run the build script only once, instead of three times:
      • as part of npm ci
      • as a separate npm run build
      • as part of npm run test
    • [ ] Add back Cypress recording integration (project id and record key)
    • [ ] Integrate lint step here as well?
    opened by daun 0
  • Add CodeQL workflow for GitHub code scanning

    Add CodeQL workflow for GitHub code scanning

    Hi swup/swup!

    This is a one-off automatically generated pull request from LGTM.com :robot:. You might have heard that we’ve integrated LGTM’s underlying CodeQL analysis engine natively into GitHub. The result is GitHub code scanning!

    With LGTM fully integrated into code scanning, we are focused on improving CodeQL within the native GitHub code scanning experience. In order to take advantage of current and future improvements to our analysis capabilities, we suggest you enable code scanning on your repository. Please take a look at our blog post for more information.

    This pull request enables code scanning by adding an auto-generated codeql.yml workflow file for GitHub Actions to your repository — take a look! We tested it before opening this pull request, so all should be working :heavy_check_mark:. In fact, you might already have seen some alerts appear on this pull request!

    Where needed and if possible, we’ve adjusted the configuration to the needs of your particular repository. But of course, you should feel free to tweak it further! Check this page for detailed documentation.

    Questions? Check out the FAQ below!

    FAQ

    Click here to expand the FAQ section

    How often will the code scanning analysis run?

    By default, code scanning will trigger a scan with the CodeQL engine on the following events:

    • On every pull request — to flag up potential security problems for you to investigate before merging a PR.
    • On every push to your default branch and other protected branches — this keeps the analysis results on your repository’s Security tab up to date.
    • Once a week at a fixed time — to make sure you benefit from the latest updated security analysis even when no code was committed or PRs were opened.

    What will this cost?

    Nothing! The CodeQL engine will run inside GitHub Actions, making use of your unlimited free compute minutes for public repositories.

    What types of problems does CodeQL find?

    The CodeQL engine that powers GitHub code scanning is the exact same engine that powers LGTM.com. The exact set of rules has been tweaked slightly, but you should see almost exactly the same types of alerts as you were used to on LGTM.com: we’ve enabled the security-and-quality query suite for you.

    How do I upgrade my CodeQL engine?

    No need! New versions of the CodeQL analysis are constantly deployed on GitHub.com; your repository will automatically benefit from the most recently released version.

    The analysis doesn’t seem to be working

    If you get an error in GitHub Actions that indicates that CodeQL wasn’t able to analyze your code, please follow the instructions here to debug the analysis.

    How do I disable LGTM.com?

    If you have LGTM’s automatic pull request analysis enabled, then you can follow these steps to disable the LGTM pull request analysis. You don’t actually need to remove your repository from LGTM.com; it will automatically be removed in the next few months as part of the deprecation of LGTM.com (more info here).

    Which source code hosting platforms does code scanning support?

    GitHub code scanning is deeply integrated within GitHub itself. If you’d like to scan source code that is hosted elsewhere, we suggest that you create a mirror of that code on GitHub.

    How do I know this PR is legitimate?

    This PR is filed by the official LGTM.com GitHub App, in line with the deprecation timeline that was announced on the official GitHub Blog. The proposed GitHub Action workflow uses the official open source GitHub CodeQL Action. If you have any other questions or concerns, please join the discussion here in the official GitHub community!

    I have another question / how do I get in touch?

    Please join the discussion here to ask further questions and send us suggestions!

    opened by lgtm-com[bot] 0
Releases(2.0.19)
Owner
🎉 Complete, flexible, extensible and easy to use page transition library for your web.
null
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
Custom navigations for Solid written in Typescript. Implement custom page transition logic and ✨ animations ✨

solid-custom-navigation Get, Set, Go! Custom navigations for Solid, written in Typescript. Implement custom page transition logic and ✨ animations ✨ .

Dirag Biswas 8 Nov 27, 2022
A cover page transition based on Vitalii Burhonskyi's Dribbble shot.

Cover Page Transition A cover page transition based on Vitalii Burhonskyi's Dribbble shot. Article on Codrops Demo Installation Install dependencies:

Codrops 37 Dec 31, 2022
Starter for Next.js projects with a basic page transition logic.

This is a Next.js project bootstrapped with create-next-app. Getting Started First, run the development server: npm run dev # or yarn dev Open http://

Antinomy Studio 23 Oct 27, 2022
Self-use version of web page theme Rocky for static blogger Gridea.

Gridea Theme Rocky Custom Self-use version of web page theme Rocky for static blogger Gridea. 中文说明 Description This is a self-use version of web page

试上高峰窥皓月. 7 Oct 7, 2022
Easy to use and flexible router for Alpine.js

alpinejs-router Easy to use and flexible router for Alpine.js Installation npm npm install @shaun/alpinejs-router yarn yarn add @shaun/alpinejs-router

Shaun 33 Dec 30, 2022
Gofiber with NextJS Static HTML is a small Go program to showcase for bundling a static HTML export of a Next.js app

Gofiber and NextJS Static HTML Gofiber with NextJS Static HTML is a small Go program to showcase for bundling a static HTML export of a Next.js app. R

Mai 1 Jan 22, 2022
🚀 Transition number values using easing functions

react-transition-value Transition / Animate number values using easing functions See Demos ⚡️ Getting started npm i react-transition-value import {

Björn 46 Dec 15, 2022
The awesomebooks project is a simple list, but separated into 3 parts and given a retro feel. The main page is where we can add books, and on another page we can see the list, and remove items. There is also a "contact-us" page.

Awesome Books This is the restructured version of the famous awesome-books project! Here you can find JavaScript broken into modules, using import-exp

Matt Gombos 12 Nov 15, 2022
Library to make your web page shareable fast and easy in all the majors social networks.

SocialShareJS This is a simple libray to make your web page shareable fast and easy. Its allow to include the social share link of the major social ne

Assis Ferreira 19 Jul 24, 2022
Easy and flexible jQuery tabbed functionality without all the styling.

JQuery EasyTabs Plugin Tabs with(out) style. EasyTabs creates tabs with all the functionality, no unwanted changes to your markup, and no hidden styli

Steve Schwartz 553 Nov 23, 2022
jQuery easy ticker is a news ticker like plugin, which scrolls the list infinitely. It is highly customizable, flexible with lot of features and works in all browsers.

jQuery Easy Ticker plugin jQuery easy ticker is a news ticker like plugin which scrolls a list infinitely. It is highly customizable, flexible with lo

Aakash Chakravarthy 208 Dec 20, 2022
Lexical is an extensible JavaScript web text-editor framework with an emphasis on reliability, accessibility and performance

Lexical is an extensible JavaScript web text-editor framework with an emphasis on reliability, accessibility and performance. Lexical aims to provide a best-in-class developer experience, so you can easily prototype and build features with confidence.

Meta 12.7k Dec 30, 2022
Pintora is an extensible javascript text-to-diagrams library that works in both browser and Node.js.

Pintora Documentation | Live Editor Pintora is an extensible javascript text-to-diagrams library that works in both browser and Node.js. Expressing yo

hikerpig 652 Dec 30, 2022
Static Page for UptimeRobot. Powered by Next.js

UptimePage Static Page for UptimeRobot. Powered by Next.js 配置 配置文件都位于 config.ts 中,你可以Fork仓库后自行修改配置。 变量名 描述 样例 Config.siteName 站点名 AHdark Status Config

AHdark 10 Aug 2, 2022
A pure JavaScript Web Page to retrieve real-time OTP through a web page and generate/scan QR codes.

2FA-Solver A pure JavaScript Web Page to retrieve real-time OTP through a web page and generate/scan QR codes. It can be used as an offline web page b

Yuthan K 8 Dec 7, 2022