Top Related Projects
Turbolinks makes navigating your web application faster
Create badass, fluid and smooth transitions between your website’s pages
Easily enable fast Ajax navigation on any website (using pushState + xhr)
pushState + ajax = pjax
History.js gracefully supports the HTML5 History/State APIs (pushState, replaceState, onPopState) in all browsers. Including continued support for data, titles, replaceState. Supports jQuery, MooTools and Prototype. For HTML5 browsers this means that you can modify the URL directly, without needing to use hashes anymore. For HTML4 browsers it will revert back to using the old onhashchange functionality.
Quick Overview
SmoothState.js is a jQuery plugin that enhances the user experience of single-page applications by providing smooth page transitions. It uses AJAX to load new content and animates the transition between pages, creating a more fluid and engaging browsing experience.
Pros
- Improves perceived performance and user engagement
- Easy to implement with minimal configuration required
- Supports browser history and deep linking
- Customizable animations and callbacks
Cons
- Depends on jQuery, which may not be ideal for modern projects
- Limited documentation and examples
- Not actively maintained (last update was in 2017)
- May conflict with other JavaScript frameworks or routing solutions
Code Examples
- Basic initialization:
$('#main').smoothState();
This code initializes smoothState on the main content container.
- Configuration with options:
$('#main').smoothState({
prefetch: true,
cacheLength: 2,
onStart: {
duration: 250,
render: function ($container) {
$container.addClass('is-exiting');
}
}
});
This example sets up smoothState with prefetching enabled, a cache length of 2 pages, and a custom onStart animation.
- Excluding specific links:
$('#main').smoothState({
anchors: 'a:not(.no-smoothState)'
});
This code tells smoothState to ignore links with the class 'no-smoothState'.
Getting Started
- Include jQuery and smoothState in your HTML:
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="jquery.smoothState.js"></script>
- Initialize smoothState in your JavaScript:
$(function() {
$('#main').smoothState({
// Options here
});
});
- Ensure your HTML structure has a main content container:
<div id="main">
<!-- Your page content here -->
</div>
- Add CSS transitions for smooth animations:
.is-exiting {
opacity: 0;
transition: opacity 0.5s ease-in-out;
}
Competitor Comparisons
Turbolinks makes navigating your web application faster
Pros of Turbolinks
- Seamless integration with Ruby on Rails applications
- Automatic handling of browser history and URL changes
- Built-in progress bar for loading indication
Cons of Turbolinks
- Can interfere with JavaScript events and DOM manipulation
- Requires careful consideration when working with third-party libraries
- May cause issues with analytics tracking without proper configuration
Code Comparison
Turbolinks:
document.addEventListener("turbolinks:load", function() {
// Your JavaScript code here
});
SmoothState.js:
$('#main').smoothState({
onStart: {
duration: 250,
render: function ($container) {
$container.addClass('is-exiting');
}
}
});
Key Differences
- Turbolinks is designed specifically for Ruby on Rails applications, while SmoothState.js is a more general-purpose JavaScript library.
- SmoothState.js provides more granular control over transitions and animations.
- Turbolinks replaces the entire body content, whereas SmoothState.js allows for partial page updates.
- SmoothState.js requires more manual configuration, while Turbolinks works out of the box with Rails.
Use Cases
- Choose Turbolinks for Rails applications seeking quick performance improvements with minimal setup.
- Opt for SmoothState.js when building custom single-page applications or requiring fine-tuned control over page transitions.
Both libraries aim to improve perceived performance and user experience by reducing full page reloads, but they cater to different development ecosystems and project requirements.
Create badass, fluid and smooth transitions between your website’s pages
Pros of Barba
- More active development and community support
- Built-in support for CSS transitions and animations
- Smaller file size and better performance
Cons of Barba
- Steeper learning curve for beginners
- Less extensive documentation compared to SmoothState.js
Code Comparison
SmoothState.js:
$('#main').smoothState({
onStart: {
duration: 250,
render: function ($container) {
$container.addClass('is-exiting');
}
}
});
Barba:
import barba from '@barba/core';
barba.init({
transitions: [{
leave(data) {
return gsap.to(data.current.container, {
opacity: 0
});
}
}]
});
Key Differences
- SmoothState.js uses jQuery, while Barba is a vanilla JavaScript library
- Barba offers more flexibility in defining custom transitions
- SmoothState.js provides easier setup for basic page transitions
- Barba supports more advanced features like prefetching and caching
Use Cases
- SmoothState.js: Ideal for simpler projects or those already using jQuery
- Barba: Better suited for modern, complex web applications with custom animations
Community and Support
- Barba has more recent updates and a larger community
- SmoothState.js has been around longer but has less frequent updates
Performance
- Barba generally offers better performance due to its smaller size and optimized code
- SmoothState.js may have slightly higher overhead due to jQuery dependency
Easily enable fast Ajax navigation on any website (using pushState + xhr)
Pros of pjax
- Lightweight and focused on core PJAX functionality
- Extensive browser support, including older versions
- Well-documented with clear usage instructions
Cons of pjax
- Less emphasis on smooth transitions and animations
- Requires more manual setup for advanced features
- Limited built-in options for customizing the user experience
Code Comparison
pjax:
document.addEventListener("pjax:send", function() {
// loading indicator
});
new Pjax({
elements: "a",
selectors: ["title", ".content"]
});
smoothState:
$('#main').smoothState({
onStart: {
duration: 250,
render: function ($container) {
$container.addClass('is-exiting');
}
}
});
Key Differences
- pjax focuses on efficient page loads without full reloads
- smoothState emphasizes smooth transitions and animations
- pjax has a more traditional JavaScript API, while smoothState uses jQuery
- smoothState provides more built-in options for customizing transitions
- pjax is generally lighter and more focused, while smoothState offers a more comprehensive solution for creating fluid user experiences
Both libraries aim to improve website performance and user experience by implementing PJAX (pushState + AJAX) functionality, but they differ in their approach and feature set.
pushState + ajax = pjax
Pros of jquery-pjax
- Lightweight and focused on AJAX-based page transitions
- Well-established with a large user base and community support
- Seamless integration with jQuery, making it easy to adopt in existing projects
Cons of jquery-pjax
- Requires jQuery as a dependency, which may not be ideal for modern projects
- Less feature-rich compared to smoothState.js, with fewer customization options
- Limited built-in support for advanced animations and transitions
Code Comparison
smoothState.js:
$('#main').smoothState({
onStart: {
duration: 250,
render: function ($container) {
$container.addClass('is-exiting');
}
}
});
jquery-pjax:
$(document).pjax('a', '#pjax-container');
$(document).on('pjax:start', function() {
$('#loading').show();
});
Both libraries aim to enhance page transitions, but smoothState.js offers more advanced features and customization options out of the box. It provides a more comprehensive solution for creating smooth, animated page transitions with fine-grained control over the loading process.
jquery-pjax, on the other hand, focuses on simplicity and ease of use, making it a good choice for projects that already use jQuery and require basic AJAX-based page loads without complex animations.
While smoothState.js has a steeper learning curve, it offers more flexibility for creating sophisticated user experiences. jquery-pjax is better suited for quick implementation of AJAX navigation in simpler projects.
History.js gracefully supports the HTML5 History/State APIs (pushState, replaceState, onPopState) in all browsers. Including continued support for data, titles, replaceState. Supports jQuery, MooTools and Prototype. For HTML5 browsers this means that you can modify the URL directly, without needing to use hashes anymore. For HTML4 browsers it will revert back to using the old onhashchange functionality.
Pros of History.js
- More comprehensive browser support, including older versions of Internet Explorer
- Provides a unified API for manipulating browser history across different browsers
- Offers additional features like state management and custom data storage
Cons of History.js
- Less focused on creating smooth page transitions
- May have a steeper learning curve due to its more extensive feature set
- Last updated in 2014, potentially outdated compared to more recent libraries
Code Comparison
History.js:
History.pushState({state:1}, "State 1", "?state=1");
History.pushState({state:2}, "State 2", "?state=2");
History.back();
History.go(2);
SmoothState.js:
$('#main').smoothState({
onStart: {
duration: 250,
render: function ($container) {
$container.addClass('is-exiting');
}
}
});
The code snippets demonstrate that History.js focuses on manipulating browser history directly, while SmoothState.js emphasizes creating smooth transitions between pages. History.js provides more granular control over the browser's history stack, whereas SmoothState.js offers a higher-level API for managing page transitions with built-in animation support.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
smoothState.js
smoothState.js is a jQuery plugin that progressively enhances page loads to give us control over page transitions. If the user's browser doesn't have the required features, smoothState.js fades into the background and never runs.
Built with smoothState.js
Below are some cool sites built with smoothState.js. Feel free to submit a pull request with your own site, or tweet me with a link.
Contributor demos
Live Sites
- Twitch Conf by Alexis Gallisá
- Interactive portfolio by Recardo Zanutta
- Refune by Victor Meyer
- Beau Han Xu London by Lawrence Gosset
- Rock Werchter by Rock Werchter
- Portfolio Site by Aaron Porter
- Open Innovation in Science by Roland Schütz
Need help?
If you need a little help implementing smoothState there are a couple things you could do to get some support:
- Post on stackoverflow using the smoothState.js tag.
- Join the Gitter room and talk to some of the contributors.
- Contact Miguel directly, he provides pair-programing help billed by the hour
Please avoid creating a Github issue with personal support requests, to keep the tracker clear for bugs and pull requests.
Intro
Imagine, for a second, how disorienting it would be if touching a doorknob teleported you to the other side of the door. Navigating the web feels like using a teleporting doorknob. Layouts change, elements rearrange or disappear, and it takes time for the user to adjust. Smooth transitions reduce the effort it takes for users to get settled into a new environment.
Javascript SPA frameworks, sometimes referred to as MVC frameworks, are a common way to solve this issue. These frameworks often lose the benefits of unobtrusive code. Writing unobtrusive javascript gives us more resilience to errors, and improved performance and accessibility.
How does smoothState.js work?
smoothState.js provides hooks that can be used to choreograph how elements enter and exit the page during navigation. It uses the time the animations are running to fetch content via AJAX to inject into the page.
smoothState.js doesn't dictate how things on the page should be animated. It supports CSS animations, as well as JS animation libraries like velocity.js.
Design philosophy and requirements
The project's main goal is to allow developers to add page transitions without having to add any logic to the backend. We keep things unobtrusive at all times.
smoothState.js initializes on containers, not links. Think of a container as a small window object embedded in the page.
- Every URL on your site should return a full layout - not just an HTML fragment
- The smoothState container needs to have an
id
set - a unique hook to tell us what to update on the page - All links and forms on the page should live within the container
These requirements makes the website resilient, since it smoothState.js can abort and simply redirect the user if an error occurs. Making each link return a full page also ensures that pages are created with progressive enhancement in mind.
Getting started
All we need to do to get started is:
- Include a copy of jQuery and jQuery.smoothState.js on your page
- Add a container with an id of
#main
and include some links inside of it - Create a new js file and run
$('#main').smoothState()
$(function() {
$('#main').smoothState();
});
By default, smoothState.js will:
- Prevent links and forms from triggering a full page load, if possible
- Use AJAX to request pages and replace the content appropriately
- Update URLs and browsing history so that browsing expectations aren't broken
smoothState.js will not add page transitions to pages. You'll need to define the animations you want to run using the hooks smoothState.js provides.
onBefore
- Runs before a page load has been startedonStart
- Runs once a page load has been activatedonProgress
- Runs if the page request is still pending and theonStart
animations have finishedonReady
- Run once the requested content is ready to be injected into the page and the previous animations have finishedonAfter
- Runs after the new content has been injected into the page and all animations are complete
Options
smoothState.js provides some options that allow customization of the plugin's functionality. The default options are overridden by passing an object into the smoothState
function.
Options example
$(function(){
'use strict';
var options = {
prefetch: true,
cacheLength: 2,
onStart: {
duration: 250, // Duration of our animation
render: function ($container) {
// Add your CSS animation reversing class
$container.addClass('is-exiting');
// Restart your animation
smoothState.restartCSSAnimations();
}
},
onReady: {
duration: 0,
render: function ($container, $newContent) {
// Remove your CSS animation reversing class
$container.removeClass('is-exiting');
// Inject the new content
$container.html($newContent);
}
}
},
smoothState = $('#main').smoothState(options).data('smoothState');
});
debug
If set to true
, smoothState.js will log useful debug information to the console, instead of aborting. For example, instead of redirecting the user to a page on an error, it might log:
No element with an id of â#mainâ in response from â/about.htmlâ.
// Default
$('#main').smoothState({ debug: false });
anchors
A jQuery selector specifying which anchors within the smoothState
element should be bound.
// Default
$('#main').smoothState({ anchors: 'a' });
hrefRegex
A regular expression to specify which anchor with a specific href property based on the regex smoothState should bind to. If empty, every href will be permitted.
// Default
$('#main').smoothState({ hrefRegex: '' });
forms
A jQuery selector specifying which forms within the smoothState
element should be bound.
// Default
$('#main').smoothState({ forms: 'form' });
allowFormCaching
Controls whether or not form submission responses are preserved in the cache. If set to true, smoothState will store form responses in the cache. This should be set to false unless you understand how caching form results will affect your website's behaviour very well.
// Default
$('#main').smoothState({ allowFormCaching: false });
repeatDelay
The minimum number of milliseconds between click/submit events. User events ignored beyond this rate are ignored. This can be used to ignore double-clicks so that the user's browser history won't become cluttered by incompleted page loads.
// Default
$('#main').smoothState({ repeatDelay: 500 });
blacklist
A jQuery selector specifying which elements within the smoothState
element should be ignored. This includes both form and anchor elements.
// Default
$('#main').smoothState({ blacklist: '.no-smoothState' });
prefetch
There is a 200ms to 300ms delay between the time that a user hovers over a link and the time they click it. On touch screens, the delay between the touchstart
and touchend
is even greater. If the prefetch
option is set to true
, smoothState.js will begin to preload the contents of the URL during that delay. This technique will increase the perceived performance of the site.
// Default
$('#main').smoothState({ prefetch: false });
prefetchOn
The name of the events to listen to from anchors when prefetching.
// Default
$('#main').smoothState({ prefetchOn: 'mouseover touchstart' });
If you would like to throttle the prefetch, do so by firing custom events.
Libraries like @tristen's hoverintent can be used to throttle prefetching based on the user's intent, by triggering a custom intent
event. To use it with smoothState.js, set intent
as the prefetchOn
option.
$('#main').smoothState({ prefetchOn: 'intent' });
Or, for the opposite effect, use something like @cihadturhan's jQuery.aim and add spider sense-like prefetching to smoothState.js.
$('#main').smoothState({ prefetchOn: 'aim' });
locationHeader
A field name to lookup among the headers from the HTTP response to alert smoothState.js of any redirected URL.
smoothState.js makes AJAX requests using XMLHttpRequest
, which silently follows redirects. This transparence prevents smoothState.js from knowing if a request resulted in a redirection.
For example, when you visit /about
and the server redirects you to /about/company
, smoothState.js is only ever informed of a successful response from /about
. The locationHeader
option gives smoothState.js a HTTP response header to consult and replace the browser's history entry with the real URI.
$('#main').smoothState({ locationHeader: 'X-SmoothState-Location' });
cacheLength
The number of pages to cache. smoothState.js can cache pages in memory, avoiding the user having to request pages more than once. Cached pages will load instantaneously.
// Default
$('#main').smoothState({ cacheLength: 0 });
loadingClass
The class to apply to the body
while a page is still loading, unless the page is received before the animations are complete.
// Default
$('#main').smoothState({ loadingClass: 'is-loading' });
scroll
Scroll to top after onStart and scroll to hash after onReady. This is default behavior, if you want to implement your own scroll behavior, set scroll: false
// Default
$('#main').smoothState({ scroll: true });
alterRequest
A function to alter a request's AJAX settings before it is called. This can be used to alter the requested URL, for example.
// Default
$('#main').smoothState({
// Param `request` is an `Object` that is currently set to be used
alterRequest: function(request) {
// Must return and `Object` that will be used to make the request
return request;
}
});
alterChangeState
A function to alter a history entry's state object before it is modified or added to the browser's history. This can be used to attach serializable data to the history entry, for example.
// Default
$('#main').smoothState({
// Param `state` is an `Object` that contains the container ID, by default
alterChangeState: function(state) {
// Must return a serializable `Object` that is associated with the history entry
return state;
}
});
onBefore
The function to run before a page load is started.
// Default
$('#main').smoothState({
// `$currentTarget` is a `jQuery Object` of the element, anchor or form, that triggered the load
// `$container` is a `jQuery Object` of the the current smoothState container
onBefore: function($currentTarget, $container) {}
});
onStart
The function to run once a page load has been activated. This is an ideal time to animate elements that exit the page and set up for a loading state.
// Default
$('#main').smoothState({
onStart: {
// How long this animation takes
duration: 0,
// A function that dictates the animations that take place
render: function ($container) {}
}
});
onProgress
The function to run only if the page request is still pending and onStart
has finished animating. This is a good place to add something like a loading indicator.
// Default
$('#main').smoothState({
onProgress: {
// How long this animation takes
duration: 0,
// A function that dictates the animations that take place
render: function ($container) {}
}
});
onReady
The function to run when the requested content is ready to be injected into the page. This is when the page's contents should be updated.
// Default
$('#main').smoothState({
onReady: {
duration: 0,
// `$container` is a `jQuery Object` of the the current smoothState container
// `$newContent` is a `jQuery Object` of the HTML that should replace the existing container's HTML.
render: function ($container, $newContent) {
// Update the HTML on the page
$container.html($newContent);
}
}
});
onAfter
The function to run when the new content has been injected into the page and all animations are complete. This is when to re-initialize any plugins needed by the page.
// Default
$('#main').smoothState({
onAfter: function($container, $newContent) {}
});
Methods and properties
smoothState
provides some methods and properties, made accessible through the element's data
property.
// Access smoothState
var smoothState = $('#main').smoothState().data('smoothState');
// Run method
smoothState.load('/newPage.html');
Properties
href
The URL of the content that is currently displayed.
cache
An object containing the cached pages after they are requested.
Methods
load(url)
This loads the contents of a URL into our container.
fetch(url)
This fetches the contents of a URL and caches it.
clear(url)
This clears a given page from the cache. If no URL is provided it will clear the entire cache.
restartCSSAnimations()
This restarts any CSS animations applying to elements within the smoothState
container.
FAQ
Help! My
$(document).ready()
plugins work fine when I refresh but break on the second page load.
smoothState.js provides the onAfter
callback function that allows you to re-run your plugins. This can be tricky if you're unfamiliar with how AJAX works.
When you run a plugin on $(document).ready()
, it's going to register only on elements that are currently on the page. Since we're injecting new elements every load, we need to run the plugins again, scoping it to just the new stuff.
A good way to do this is to wrap your plugin initializations in a function that we call on both $.fn.ready()
and onAfter
. You'll want to specify the context each time you initialize the plugins so that you don't double-bind them. This is called a "module execution controller".
Contribute
We're always looking for:
- Bug reports, especially those for aspects with a reduced test case
- Pull requests for features, spelling errors, clarifications, etc.
- Ideas for enhancements
- Demos and links to sites built with smoothState.js
Top Related Projects
Turbolinks makes navigating your web application faster
Create badass, fluid and smooth transitions between your website’s pages
Easily enable fast Ajax navigation on any website (using pushState + xhr)
pushState + ajax = pjax
History.js gracefully supports the HTML5 History/State APIs (pushState, replaceState, onPopState) in all browsers. Including continued support for data, titles, replaceState. Supports jQuery, MooTools and Prototype. For HTML5 browsers this means that you can modify the URL directly, without needing to use hashes anymore. For HTML4 browsers it will revert back to using the old onhashchange functionality.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot