Taxi.js: Smooth Transitions for Modern Web Apps

13/03/2017

Rating: 4.09 (2407 votes)

In the fast-paced world of web development, delivering a seamless and responsive user experience is paramount. Traditional full-page reloads can often disrupt the flow, leading to a less than ideal experience for your visitors. This is where modern JavaScript libraries come into play, and among them, Taxi.js stands out as a robust solution for implementing elegant AJAX navigation and smooth transitions.

How do I create a new taxi instance?
When creating a new Taxi instance, you can pass an object of options into the constructor: const taxi = new Core({ ... }) Let's look at these in more detail. Please see Renderers for more information. Please see Transitions for more information. Links is a CSS selector which Taxi uses to decide if a clicked link should be transitioned or not.

Taxi.js is the spiritual successor to the widely used but now unmaintained Highway.js library. It offers a sophisticated yet straightforward approach to building single-page application (SPA)-like navigation without the full complexity of a complete SPA framework. By intelligently replacing only the necessary content, Taxi.js ensures your website feels incredibly fluid, enhancing the overall user experience dramatically.

Table

What is Taxi.js and Why Should You Care?

At its core, Taxi.js is a JavaScript library designed to revolutionise how users interact with your website. Instead of the browser performing a full page reload every time a link is clicked, Taxi.js intercepts these clicks, fetches the new page content via AJAX, and then smoothly transitions the new content into view while removing the old. This process minimises loading times and creates a much more engaging and continuous browsing experience.

For developers familiar with Highway.js, Taxi.js provides a familiar yet significantly enhanced environment. It was built with the lessons learned from its predecessor, addressing common pain points and introducing powerful new features that make it even more versatile and reliable for modern web projects. If you've been looking for a robust, easy-to-implement solution for dynamic page transitions, Taxi.js is definitely worth your attention.

Key Features and Advantages Over Highway.js

Taxi.js isn't just a rehash; it brings substantial improvements that streamline development and enhance performance:

  • URL-based Routing: Offers a more intuitive and powerful way to define which transitions apply to which page navigations.
  • Better Cache Management: Optimised caching mechanisms ensure faster subsequent visits to previously loaded pages.
  • Ability to Preload URLs: Proactively fetches content for links that users are likely to click, making transitions feel instantaneous.
  • Blocks Navigation During Active Transition: Prevents multiple simultaneous navigations, ensuring a clean and controlled transition flow (this can be opted out if desired).
  • Auto Runs JavaScript on the New Page: Automatically re-executes scripts in the newly loaded content, simplifying dynamic content integration.
  • Previous Page's Content is Automatically Removed: Cleans up the DOM efficiently after a transition, reducing memory footprint (this can also be opted out).
  • Click Events on Links Can Be Intercepted: Allows developers to use stopPropagation for link clicks without resorting to hacks, offering cleaner event handling.

While sharing a similar philosophy, Taxi.js introduces several API and attribute changes compared to Highway.js. Understanding these differences is crucial for a smooth migration or new implementation:

Feature/APIHighway.jsTaxi.js
Wrapper Attributedata-router-wrapperdata-taxi
View Attributedata-router-viewdata-taxi-view
Ignore Attributedata-router-disableddata-taxi-ignore
Link Attach/Detachattach, detachNot needed (delegation)
Redirection MethodredirectnavigateTo
Renderer MethodN/AinitialLoad
Old Content RemovalManual (from.remove())Automatic
Parameter StructureDifferentDifferent

The move away from `attach` and `detach` methods to a delegation-based approach simplifies event listening, making your code cleaner and more efficient. The `navigateTo` method name is also arguably more descriptive than `redirect` for client-side navigation.

Navigating the Roads: Understanding Taxi.js Routing

One of the most powerful features of Taxi.js is its robust URL-based routing system. This system allows you to precisely control which transition is used when a user navigates between specific pages. Routes are defined using regular expressions, offering immense flexibility.

You define routes via the addRoute method, which takes three arguments: a regex to match against the current URL, a regex to match against the new URL after navigation, and the name of the transition to use if both regex patterns match. As soon as a match is found, that transition is chosen.

Examples of Routing Rules:

// Transition from a blog page to the homepage
taxi.addRoute('/blog/.*', '', 'blogToHome')

// Transition the homepage to any other page
taxi.addRoute('', '.*', 'fromHome')

// Transition from the about page, to the contact page
taxi.addRoute('/about', '/contact', 'aboutToContact')

It's important to note a few key aspects of how Taxi.js handles these regular expressions:

  • Your regex is automatically wrapped inside ^ and $. This means a regex of `/api` will match `/api` but not `/v2/api`. Keep this in mind for precise matching.
  • All trailing slashes are stripped from URLs before they are matched. So, `/` will not match your homepage; you should use `''` or `/?` instead.
  • Since they are run as `RegExp`, there's no need to escape slashes within your patterns.

The Importance of Route Ordering

The order in which you declare your routes matters significantly. Routes are tested sequentially, and the first match found is the one that gets used. This means you should always declare more specific rules before more general, catch-all rules.

What is routing in taxi?
Routing in Taxi is used to choose which Transition to choose when a user performs a navigation. They are defined via the addRoute method, and consist of a regex to run against the current URL, a regex to run against the new URL after the navigation, and the transition to use if matched. Here are a few examples:

Consider the following example:

// Bad Ordering
taxi.addRoute('/pages/.*', '', 'somethingElse') // General rule first
taxi.addRoute('/pages/specific', '', 'something') // Specific rule second

// Good Ordering
taxi.addRoute('/pages/specific', '', 'something') // Specific rule first
taxi.addRoute('/pages/.*', '', 'somethingElse') // General rule second

In the "bad" example, if a user navigates from `/pages/specific` to the homepage, the first general rule (`/pages/.*`) would match and execute the `somethingElse` transition, completely ignoring your more specific `something` transition. By placing the more specific rule first, as in the "good" example, you ensure that it takes precedence when applicable, allowing the general rule to act as a fallback for other `/pages/` URLs.

Getting Started: Installing and Initialising Taxi.js

Implementing Taxi.js in your project is a straightforward process. Here's how you can get started:

1. Get the Package

You can include Taxi.js in your project using your preferred package manager:

  • npm:npm i @unseenco/taxi
  • yarn:yarn add @unseenco/taxi
  • pnpm:pnpm add @unseenco/taxi

2. Setting Up Your JavaScript

Once the package is installed, you need to import Core from @unseenco/taxi and create a new instance:

import { Core } from '@unseenco/taxi'
const taxi = new Core()

// or if you prefer
import * as Taxi from '@unseenco/taxi'
const taxi = new Taxi.Core()

3. Amending Your HTML

For Taxi.js to work its magic, you need to prepare your HTML structure. Add the data-taxi attribute to the parent element that wraps the content you want to replace during a transition. Then, add data-taxi-view to the specific element within that parent that will be replaced.

<main data-taxi>
<article data-taxi-view>
... your page content ...
</article>
</main>

Important Note: The element with data-taxi-viewmust be the only child of the element with data-taxi. This strict structure ensures Taxi.js can efficiently manage content replacement.

Now, when you navigate your application, the content within data-taxi-view will be seamlessly replaced with the corresponding content from the target URL, rather than triggering a full page reload.

Using Via CDN

For simpler projects or quick testing, you can also include Taxi.js directly via a CDN:

<script src="https://unpkg.com/@unseenco/[email protected]/dist/e.umd.js" crossorigin></script>
<script src="https://unpkg.com/@unseenco/[email protected]/dist/taxi.umd.js" crossorigin></script&br>
<main data-taxi>
<article data-taxi-view>
... your page content ...
</article>
</main>

<script>
const t = new taxi.Core()
</script>

Note that when using the CDN, the main export is `taxi` with a lowercase 't'.

How Taxi.js Handles Links

By default, Taxi.js is smart about which links it attempts to transition. For security and practical reasons, it will only transition links to a domain which is the same as the current URL. Furthermore, it explicitly avoids transitioning links that:

  • Have the data-taxi-ignore attribute present on the link element.
  • Are anchor links for the current page (e.g., #section).
  • Have a target attribute present (e.g., target="_blank").

You have full control over this behaviour through the links option, which allows you to define a custom CSS selector to determine which links Taxi.js should intercept.

Fine-Tuning Your Ride: Essential Taxi.js Options

When creating a new Taxi.js instance, you can pass an object of options into the constructor to customise its behaviour. This allows you to tailor the library to your specific project needs.

const taxi = new Core({
// ... options here ...
})

Here's a breakdown of the most commonly used options:

OptionTypeDefaultDescription
renderersObject.<string, Renderer>{}Defines custom renderers for specific page types, allowing bespoke logic to run when a page is loaded.
transitionsObject.<string, Transition>{}Defines custom transitions to use between pages, enabling unique animations and effects.
linksstringa:not([target]):not([href^=\#]):not([data-taxi-ignore])A CSS selector that Taxi.js uses to decide if a clicked link should be transitioned. Customise this to fine-tune link interception.
removeOldContentbooleantrueDetermines if Taxi.js should automatically remove the previous page's content after a transition's onLeave method finishes. Set to false to disable.
allowInterruptionbooleanfalseControls whether further navigation is blocked while a transition is in progress. Set to true to allow interruptions.
bypassCachebooleanfalseIf set to true, the internal cache for fetched URLs will be completely disabled. By default, content is cached for faster repeated visits.
enablePrefetchbooleantrueControls whether Taxi.js preloads links on your website when a mouseenter or focus event is triggered. Set to false if you want to implement your own preloading strategy.
reloadJsFilterboolean|function(element: HTMLElement)trueDetermines if JavaScript within the new page content should be re-executed. Can be a boolean or a function for granular control.
reloadCssFilterboolean|function(element: HTMLLinkElement)trueDetermines if CSS link elements within the new page content should be reloaded. Can be a boolean or a function for granular control.

The `links` option is particularly powerful. Its default value already ignores links with a `target` attribute, anchor links for the current page, or those with `data-taxi-ignore`. You can extend this selector to include or exclude other types of links based on your application's needs.

What is full documentation taxi?
Full Documentation Taxi is a js library for adding AJAX navigation and beautiful transitions to your website. It was designed as a drop-in replacement for Highway.js which is sadly no longer maintained. data-taxi, data-taxi-view, data-taxi-ignore are to be used instead of data-router-wrapper, data-router-view, data-router-disabled respectively.

Regarding caching, even if `bypassCache` is `false` (default behaviour), you can force specific pages to always be fetched and never loaded from cache by adding the `data-taxi-nocache` attribute to the `data-taxi-view` element on that particular page.

Frequently Asked Questions (FAQs)

Q: What is meant by "full documentation taxi"?

A: When you see "full documentation taxi", it refers to the comprehensive guide and reference material available for the Taxi.js library. This documentation covers all aspects of the library, from installation and basic setup to advanced routing, custom transitions, renderers, and all available configuration options, helping developers understand and utilise its full capabilities.

Q: How does routing work in Taxi.js?

A: Routing in Taxi.js is managed through the taxi.addRoute() method. You define rules using regular expressions that match the current and target URLs during navigation. When a match is found, a specified transition is triggered. It’s crucial to remember that routing rules are processed in the order they are declared, and more specific rules should precede more general ones to ensure correct behaviour.

Q: Can I use Taxi.js with a CDN?

A: Yes, you can easily use Taxi.js via a Content Delivery Network (CDN). This is particularly useful for quick prototyping or for projects where you don't use a module bundler. You simply include the necessary script tags in your HTML, pointing to the Taxi.js UMD build available on services like unpkg.com.

Q: What types of links does Taxi.js NOT transition by default?

A: By default, Taxi.js intelligently avoids transitioning several types of links to prevent unexpected behaviour. These include links with a data-taxi-ignore attribute, anchor links pointing to sections within the current page (e.g., #section-id), and links that have a target attribute (e.g., target="_blank", which typically opens in a new tab or window).

Q: Can I disable the cache for specific pages using Taxi.js?

A: Yes, while Taxi.js caches page content by default for performance, you can disable caching for individual pages. To do this, simply add the data-taxi-nocache attribute to the data-taxi-view element on the page you wish to exclude from caching. This ensures that the content for that specific URL is always fetched fresh from the server.

Taxi.js offers a powerful and elegant solution for creating highly interactive and performant web applications. By seamlessly handling AJAX navigation and providing robust control over page transitions, it significantly elevates the user experience, making your website feel modern, fast, and incredibly responsive. Whether you're upgrading an existing Highway.js project or starting fresh, Taxi.js provides the tools you need to build a truly dynamic web presence.

If you want to read more articles similar to Taxi.js: Smooth Transitions for Modern Web Apps, you can visit the Taxis category.

Go up