Select Page

Exploring The Turbo Drive Navigation Progress Bar In Lucee CFML

Published: February 8, 2023

When you enable Turbo Drive in a Hotwire application, Turbo Drive intercepts native link clicks and form submissions and then re-implements them using the browser’s fetch() API. If a fetch() call takes longer than 500ms to complete (a configurable default), Hotwire will render a progress bar at the top of the window. The progress bar is a simple <div> element that can be lightly styled using CSS. I just wanted to take a quick look at how the progress bar works in a ColdFusion application.

View this code in my ColdFusion + Hotwire Demos project on GitHub.

To test Hotwire’s progress bar functionality, I created a small ColdFusion application with three pages:

  • index.cfm – loads instantly.
  • products.cfm – sleeps between 1-5 seconds before rendering.
  • about.cfmsleeps 25-seconds before rendering.

These pages – and their embedded sleep() commands – give me enough time to look at the DOM (Document Object Model) while the progress bar is being rendered. Here’s my about.cfm page, which does the most sleeping:

	sleep( 25000 ); // 25-seconds.
<cfmodule template="./tags/page.cfm">
			ColdFusion + Hotwire Navigation Progress Bar Demo
			<a href="">Home</a> -
			<a href="products.htm">Products</a> -
			<a href="about.htm"><strong>About</strong></a>
		<!--- ... truncated, filler copy ... --->

The sleep( 25000 ) function call is the only thing of note in this template – the rest of the template is just navigation links and filler copy. And, if I load this app and then navigate to the about.cfm page, we get the following page output:

As you can see, the Turbo Drive progress bar is implemented as an empty div element with position: fixed. It’s injected in between the <head> and <body> tags. And, to be honest, I didn’t even know that you could put DOM content in between those two elements. I’m sure that works to side-step display and z-index issues that might occur if placed inside the body tag.

ASIDE: Turbo Drive is using a z-index of 2,147,483,647. This is the largest value that can fit inside a 32-bit signed integer. According to this post by Tan Li Hau, the CSS specification doesn’t mention any limit on z-index; however, the z-index value is often stored as a 32-bit signed integer, making the Turbo Drive z-index value the highest possible value.

The .turbo-progress-bar CSS class definition is defined in a <style> tag that is prepended to the <head> tag as the first child. This means, from a cascading and specificity standpoint, overriding the progress bar style is extremely easy. All you have to do is define your own .turbo-progress-bar property block. For example, I changed the background to pink:

.turbo-progress-bar {
	background-color: #ec005a ;

And, when I re-render the page and navigate to about.cfm, I get pink!

The Turbo Drive progress bar rendered as pink.

Hotwire’s Turbo Drive feels like such an elegant drop-in solution to progressively enhance a ColdFusion application. I love all this attention to detail that the Basecamp team put into this stuff.

Check out the license.