Premise
Building upon the challenge about tabbed navigation, we will explore pagination with Turbo Frames. Indeed, it turns out pagination is just a special case of tabs. Turbo Frames provide a very performant way to switch between “windows” of a dataset, but they come with some gotchas.
Starting Point
In this example we are looking at a table of employees with alphabetical pagination. Upon page load, a Turbo Frame is lazily loaded from pageA.html. Our goal is to implement the pagination using the query parameter page
, and make it play nicely with the browser history (i.e. it can be navigated using the back and forward buttons).
Note that we keep the pagination itself inside the frame. One of the advantages is that way we can server-side render the active page and don’t have to fall back to marking it after the fact using an event handler.
Challenge
The challenge we face is twofold:
- The client side routing of
?page=A|B|C
to populate the Turbo Frame isn’t yet implemented. A click on a pagination link will set itssrc
attribute to/?page=B
for example, but this just serves back our index.html. In theturbo:before-fetch-request
event, we need to modify this URL to return the actualpageA|B|C.html
locations. - If we implement this, the
data-turbo-action="advance"
attribute will ensure that nowpageA|B|C.html
will be put into the browser’s history, but we don’t want that, because reloading the page now will serve the bare Turbo Frames again. So onturbo:frame-load
, we have to make sure the browser’s last history entry is replaced with the respective?page=A|B|C
query string again.
Here’s a preview of how the result should look like:
Caveats
- To make the page reloadable, you have to manipulate the browser history, because using by promoting navigation to full page visit, the URL is rewritten to the bare Turbo Frame’s location. (There’s a hint in the Stackblitz example)
- Note that if it feels like we are bending over backwards a bit here, that’s because we are. Of course it would be easier to just server side render the whole layout and be done with it. But by embracing the constraints we are further pushing the limits of our understanding of how Turbo actually works.
Teaser
- Could we translate this behavior to infinite horizontal/vertical scrolling?