New releases

Hotwire Club tooling is now open-source

Explore the agentic skills pack and the MCP server for building assistant workflows.

Turbo Frames - Tabbed Navigation

Drive tabbed navigation using Turbo Frames.

View Solution on Patreon
Turbo Frames - Tabbed Navigation

Premise

Turbo Frames are an exceptionally good fit for tabbed navigation, but come with a few pitfalls. For example, quite usually you want to exchange not only the content of the tab, but also display which tab is active. Since you cannot exchange two turbo frames from one response, you have to fall back to Turbo Streams or custom Javascript.

Additionally, depending on your application’s requirements you might want to navigate through the browser history using the back and forward buttons. We are going to cover both these obstacles in this challenge.

Starting Point

The StackBlitz example for this challenge presents a simple tabbed content area for an imaginary real estate website. The navigation links point to the respective pages, but using data-turbo-frame="content", they specify the <turbo-frame> as a target.

Challenges

  • How can you render the “active” tab without falling back to Turbo Streams or Stimulus?
  • How can we add the current state to the browser’s history, and recover the active tab when navigating with the browser’s back and forward buttons?

Here’s a preview of the end result:

Caveats

  • using the turbo:click event to adjust the active tab’s styling is tempting, but doesn’t quite work (why?)
  • don’t try to implement pushState yourself, because you will interfere with how Turbo adds restoration identifiers to the state history - there’s a built in solution that works better

Teaser

  • using a Stimulus controller, how would you make your solution portable?

This is The Hotwire Club

46 hands-on challenges with detailed solutions, published biweekly since 2023. Subscribe to access all solutions and join the Discord community.

Subscribe on Patreon

More from

Turbo Frames - Form Submission Loading States
10 March 2026

Add loading feedback to form submissions inside Turbo Frames using busy attributes and data-turbo-submits-with.

Turbo Frames - Using External Forms
03 February 2026

Refer to external forms from within a Turbo Frame

Turbo Frames - Loading Spinner
20 January 2026

Display a loading spinner while a Turbo Frame is `busy` fetching content asynchronously

Cookies
essential