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
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
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
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.