I’m trying to use turbo frames for the full navigation of my Rails app.
#index.html.erb
<%= turbo_frame_tag "page_content" do %>
<div class="flex flex-col items-center">
<h1 class="text-3xl font-bold">Home</h1>
</div>
<%= link_to "Page 1", page_1_path %>
<% end %>
#page_1.html.erb
<%= turbo_frame_tag "page_content" do %>
<div class="flex flex-col items-center">
<h1 class="text-3xl font-bold">Page 1</h1>
</div>
<%= link_to "Page 2", page_2_path %>
<% end %>
#page_2.html.erb
<%= turbo_frame_tag "page_content" do %>
<div class="flex flex-col items-center">
<h1 class="text-3xl font-bold">Page 2</h1>
</div>
<% end %>
The links are working as expected, replacing the contents of the turbo_frame with the new content from the corresponding pages, but I would like the URL to be updated and the back/forward buttons in the browser to function.
I’ve searched around, and come across this stimulus controller from turbo_frame_history_controller.ts · GitHub.
I’ve implemented it as so
#history_controller.js
import { navigator } from '@hotwired/turbo'
import { Controller } from 'stimulus'
import { useMutation } from 'stimulus-use'
export default class extends Controller {
connect () {
console.log("heyoo");
useMutation(this, { attributes: true })
}
mutate (entries) {
entries.forEach((mutation) => {
if (mutation.type === 'attributes' && mutation.attributeName === 'src') {
const src = this.element.getAttribute('src')
if (src != null) { navigator.history.push(new URL(src)) }
}
})
}
}
I’m confused how this controller works though and if it is what I’m actually looking for. I have tried putting the controller in my app/javascript/controllers/history_controller.js
and tried wrapping my turbo_frame_tag in index.html.erb
in a
<div data-controller="history">
but the URL still doesn’t change and the back/forward buttons still don’t work. The console.log
does log as expected though.
What am I missing?
Also, side note, I’m getting this when webpacker compiles the above stimulus controller
[Webpacker] Though the "loose" option was set to "false" in your @babel/preset-env config, it will not be used for @babel/plugin-proposal-private-property-in-object since the "loose" mode option was set to "true" for @babel/plugin-proposal-class-properties.
The "loose" option must be the same for @babel/plugin-proposal-class-properties, @babel/plugin-proposal-private-methods and @babel/plugin-proposal-private-property-in-object (when they are enabled): you can silence this warning by explicitly adding
["@babel/plugin-proposal-private-property-in-object", { "loose": true }]
to the "plugins" section of your Babel config.
Not sure what to make of it.
Thank you for any suggestions!