Rambling Thought: Suggestions for deep-linking to "auxiliary" routes

Some quick background: in the Angular world, the router allows you to define primary routes and auxiliary routes. I was able to use these auxiliary routes to deep link to all sorts of secondary interfaces like modal windows and fly-out panels. It’s a very attractive feature of the Angular framework.

I’ve been contemplating how to do something similar (albeit more limited / constrained) in the Hotwire framework. So far, the approach I’ve been thinking about does this:

  • Auxiliary link opens in Turbo Frame.
  • Auxiliary link advances URL to point to Auxiliary view.

The upside to this approach is that it can be 100% progressively enhanced (ie, work without JavaScript) and is the least complex. The downside to this approach is that if the user refreshes the page at that point, I’ll lose the state of the primary route and render a page that contains only the auxiliary view.

For the last few days, I’ve been trying to noodle on ways to both advance the URL and keep both routes in play. I think for that, I’d have to use a query-string param. Imagine something like:

/my/main/route.htm?auxiliary=some.other.action

This could still open into a Turbo Frame; and, on the server-side I could probably have some logic that:

  • If auxiliary is defined.
  • And, I’m in a Turbo-Frame (HTTP header)
  • Only render the auxiliary view.

But, then I get stuck on the “what if the user refreshes the page?” I’ve seen some writing where people will look at the URL and then use client-side JavaScript to programmatically trigger the Turbo Frame to be visited. I could probably simplify that to just predefine the src attribute of the <turbo-frame> to point to the same URL.

But, at that point, I have to use JavaScript in order to get the same view state to render. (to fetch the Turbo Frame content).


Oh, I just had a thought as I’m writing this! What if the refresh renders a Turbo Frame that contains a fallback link to point to the auxiliary view itself. Meaning, something like:

<turbo-frame src="/path/to/view.htm?auxiliary=some.other.action">

	<!-- Static button that will show for when Hotwire hasn't loaded. -->
	<a href="/some/other/action.htm">
		Open Auxiliary View
	</a>

</turbo-frame>

This all becomes much simpler if I depend on Hotwire loading, in so much as I can depend on the Turbo Frame to kick into action. But, I’m still trying to approach Hotwire as a progressive enhancement with functional fallbacks. But, maybe by the time I’m thinking about auxiliary routes, I need to start depending on Hotwire.

Apologies for the stream of conscience here - I’ve been going around in circles in my head for days and my Google searches haven’t yielded too much. If anyone has any suggestions, I’m all ears!

This is an interesting concept. I’ve done something similar a few times.
I usually let the backend handle this sort of thing so I would change the turbo-frames src based on a query string or something.

For example:
If you have a list of database objects. And a modal pops up when you hit edit.
I would have a query string that takes the id of the element you want to edit, then in the backend, I’ll check if it exists and if it does I’ll add the correct src to the frame. This way when you hit refresh it’s the query string that stores the state of the modal and the URL path itself that stores the rest of the page’s state. You could even rely on multiple query strings if the list has pagination and requires more state handling.

I’m not sure how this would work in a frontend-centric scenario though. But I’m curious to see if it could be made more generic than what I’m doing.

At least dynamically setting the <turbo-frame> [src] attribute sounds like it’s something people are doing. My main concern there was that I’m still requiring Hotwire to run and load the frame content. But, maybe if I’m dealing with modal workflows, mandating JavaScript is OK (I’m new to this and still trying to figure out where that line is between pragmatic and dogmatic).

I had thought about maybe trying to statically render both the main page and the modal (auxiliary) page in the same request. But, the problem is that the secondary view won’t know that its in a Turbo Frame since it’s not being requested by Turbo. I could “fake it”, but then that’s even more logic that I have to include.

My brain has been going around in circles on this stuff!

You could also dynamically set the turbo-frame content instead of the src
Leaving it blank if the query parameter is not set.

In DotNet this is often how I handle frames anyway. Having the raw URL display nothing and using query strings to tweak the output