Skip to content
/ astro Public

Astro integration for swup 🚀

Notifications You must be signed in to change notification settings

swup/astro

Repository files navigation

@swup/astro

Make your site feel like a snappy single-page app — without any of the complexity.

Enable smooth page transitions, smart preloading and more with this Astro integration for swup.

What is swup?

Swup is a versatile and extensible page transition library for multi-page apps. It manages the complete page load lifecycle and smoothly animates between the current and next page. In addition, it offers many other quality-of-life improvements like caching, smart preloading, native browser history and enhanced accessibility.

Learn more about swup in the official docs.

Installation

First, install the @swup/astro package using your package manager.

npm install @swup/astro

Then, apply the integration to your astro.config.* file using the integrations property:

import { defineConfig } from 'astro/config';
import swup from '@swup/astro';

export default defineConfig({
  integrations: [swup()]
});

Usage

Once the integration is installed, swup will handle and animate page visits. The necessary script is automatically added on every page of your website. Try navigating between different pages via links — you should no longer see browser refreshes and find page requests passing through swup under the Network tab in your browser dev tools.

The next step: fine-tune your setup by reading up on available configuration flags.

Content containers

If you're using semantic markup and your main content area is wrapped in a main tag, swup will work without modifications to your site. Should you wish to replace other content containers instead of or in addition to that, edit the containers options.

Animations

This integration enables swup's 'fade' theme for animated page transitions out of the box.

Custom animations

If you want to write your own animation styles, disable the theme option. You then need to add an animation class to your animated elements and write the animation styles in CSS. See below for an example fade animation. Refer to the swup docs for a full example setup.

export default defineConfig({
  integrations: [
    swup({ theme: false })
  ]
});
<main class="transition-fade">
  <h1>Welcome</h1>
</main>
html.is-changing .transition-fade {
  transition: 0.4s;
  opacity: 1;
}
html.is-animating .transition-fade {
  opacity: 0;
}

Usage without animations

If you don't need animated page transitions and just want to use swup for its preloading and caching features, that's fine too! In that case, disable the theme option and pass in a boolean false for the animationClass option as well.

export default defineConfig({
  integrations: [
    swup({ theme: false, animationClass: false })
  ]
});

Configuration

The integration has its own options for enabling and fine-tuning swup features. Change these in the astro.config.* file which is where your project’s integration settings live. These are the defaults:

import { defineConfig } from 'astro/config';
import swup from '@swup/astro';

export default defineConfig({
  integrations: [
    swup({
      theme: 'fade',
      animationClass: 'transition-',
      containers: ['main'],
      cache: true,
      preload: true,
      accessibility: true,
      progress: false,
      routes: false,
      smoothScrolling: false,
      updateBodyClass: false,
      updateHead: true,
      reloadScripts: false,
      debug: false,
      loadOnIdle: true,
      globalInstance: false,
    })
  ]
});

config.theme

Use one of swup's predefined themes to get started with animated page transitions.

Set to false if you want to define your own animation styles.

{
  theme: 'fade' | 'slide' | 'overlay' | false
}

config.animationClass

If you're not using one of the provided themes, you will need this class for defining your own animation styles.

The class prefix for detecting animation timing. Swup will wait for all CSS transitions and keyframe animations to finish on these elements before swapping in the content of the new page. The default option will select all elements with class names beginning in transition-.

{
  animationClass: 'transition-'
}

config.containers

The content containers to be replaced on page visits. Usually the <main> element with the content of the page, but can include any other elements that are present across all pages. Defaults to the first main tag of the page.

Note: Only elements inside of the body tag are supported.

{
  containers: ['#content', '#nav']
}

config.cache

The built-in cache keeps previously loaded pages in memory. This improves speed but can be disabled for highly dynamic sites that need up-to-date responses on each request.

{
  cache: false
}

config.preload

Enable smart preloading. Will fetch a page in the background when hovering a link. Also prefetches all pages with a [data-swup-preload] attribute. Useful for main navigations to ensure all menu items load instantly.

{
  preload: false
}

config.accessibility

Enhance accessibility for screen readers by announcing page visits and focussing the newly updated content after page visits.

{
  accessibility: true
}

config.progress

Display a progress bar for all requests taking longer than ~300ms.

{
  progress: true
}

The progress bar has a class name of swup-progress-bar you can use for styling.

.swup-progress-bar {
  height: 4px;
  background-color: blue;
}

config.routes

Use path and route names to allow choosing between animations. Given a list of URL patterns, uses path-to-regexp to identify named routes and adds them as classnames to use for styling animations, e.g. from-route-home or to-route-project.

{
  routes: [
    { name: 'home', path: '/:lang?' },
    { name: 'projects', path: '/:lang/projects' },
    { name: 'project', path: '/:lang/project/:slug' }
  ]
}

Navigating from /en/ to /en/project/some-project/ will add these classes:

<html class="is-animating from-route-home to-route-project">

config.smoothScrolling

Enable acceleration-based smooth scrolling, animated scroll positions between page visits and for anchor jump links.

{
  smoothScrolling: true
}

config.updateBodyClass

Update the body class after each page visit. Useful if you use classes on the body element for styling site sections.

{
  updateBodyClass: true
}

config.updateHead

Update the contents of the head tag after each page visit. Useful if you have differing stylesheets per section of your site.

{
  updateHead: true
}

config.reloadScripts

Re-run any script tags inside the head and body on every page view. Helpful as a last resort for sites with limited control over the included scripts. Beware: Running scripts without destroying previous ones can cause memory leaks and potentially break your page.

{
  reloadScripts: true
}

config.debug

Add debug output by swup and its plugins to the browser console. Useful during development.

{
  debug: true
}

config.loadOnIdle

Swup is a progressive enhancement and doesn't need to be loaded immediately. By default, this integration will only initialize swup when the browser is idle, after the document has finished loading. This improves first-load performance of the site. If for whatever reason you need to initialize swup immediately on load, set this option to false.

{
  loadOnIdle: true
}

config.globalInstance

Store the initialized swup instance in window.swup. Useful if you need to add custom hooks or plugins.

{
  globalInstance: true
}

Advanced usage

Access to the swup instance

For more advanced usage like registering hook handlers or installing custom plugins, you need access to the swup instance itself. Enable the globalInstance option to have the swup instance available at window.swup. You can then use swup's API directly.

<script>
  window.swup.use(new MyCustomSwupPlugin())
</script>

Control over the initialization

If you need more granularity during the initilization process itself, consider following the manual swup setup instead:

<script>
  import Swup from 'swup';
  import SwupPreloadPlugin from '@swup/preload-plugin';
  const swup = new Swup({
    plugins: [new SwupPreloadPlugin()]
  });
</script>

Troubleshooting

Having trouble implementing swup? Check out the official docs, look at past issues or create a new discussion.

You can also check the Astro Integration Documentation for more on integrations.

Contributing

This package is maintained by the swup core team. You're welcome to submit an issue or PR.

Changelog

See Changelog for a history of changes to this integration.