Using Turbo Frames for Navigation

Navigating the intricacies of Turbo Frames can be both rewarding and challenging. These custom HTML elements present a method to refine the user experience on web applications. Let's explore some patterns and use-cases that can be achieved with Turbo Frames.

Turbo Frames for Tabbed Navigation

Have you considered using Turbo Frames for tabbed navigation? On paper, it seems like a good fit. However, there are nuances to be aware of. For instance, while you might want to switch out not just the content of a tab but also highlight the active tab, you'll find that you can't swap two Turbo Frames with a single response from the server. This means you might need to consider Turbo Streams or custom Javascript.

Imagine you're developing a real estate website with tabbed content. The navigation links direct to their respective pages, but they use data-turbo-frame="content" to target the <turbo-frame>. Here's where it gets tricky: how do you render the "active" tab without leaning on Turbo Streams or Stimulus? Moreover, how do you keep track of the current state in the browser's history, ensuring the active tab remains when using the browser's navigation buttons?

While hooking into the turbo:click event might seem like a solution to adjust the active tab's styling, it doesn't quite fit the bill. And manually implementing pushState can lead to conflicts with Turbo's restoration identifiers.

However, there's a workaround. By utilizing the turbo:frame-load event, you're alerted every time the frame content reloads. This event's target is the Turbo Frame, revealing the loaded URL in its src attribute. By comparing this to the tab navigation's links' hrefs, you can pinpoint the active tab. Additionally, by adding data-turbo-action="advance" attributes to all tab navigation links, frame navigation is promoted to page visits, ensuring an entry in the browser's history with a restoration identifier.

Turbo Frames for Pagination

Expanding on the concept of tabbed navigation, Turbo Frames can also be applied to pagination. At its core, pagination is akin to tabs. Turbo Frames facilitate a method to switch between "windows" of a dataset, but there are nuances to be aware of.

Consider a table of employees with alphabetical pagination. Upon page load, a Turbo Frame is lazily loaded from pageA.html. The objective is to implement pagination using the page query parameter while ensuring compatibility with the browser history.

But there are hurdles. The client-side routing of ?page=A|B|C to populate the Turbo Frame isn't in place. A click on a pagination link sets its src attribute to /?page=B, which defaults to the index.html. The turbo:before-fetch-request event requires a URL adjustment to fetch the actual pageA|B|C.html locations. And with the data-turbo-action="advance" attribute, pageA|B|C.html is added to the browser's history, which isn't ideal for reloading.

The solution involves adjusting the URL requested by the Turbo Frame to fetch one of pageA|B|C.html. But with the data-turbo-action="advance" on the pagination links, a browser history entry with pageA|B|C.html is created. This needs correction. Using the Turbo.navigator.history object, that history entry can be replaced with the appropriate ?page=A|B|C again.

While tapping into a private API might seem unconventional, it's sometimes necessary to fully grasp how Turbo operates.

In summary, Turbo Frames provide opportunities to refine web navigation. With a clear understanding and some adjustments, both tabbed navigation and pagination can be effectively managed.

P.S. Join The Hotwire Club on Patreon to get priority access to these nibbles.

Supercharge Your Rails App

Upgrade Your Tech Stack for a Smoother Dev Experience and Increased Profits.

Order a Review