DEV Community

Mike Rogers ✈️
Mike Rogers ✈️

Posted on

Persist Scroll Positions with Hotwire Turbo

Persisting the scroll position of an element is a nice way to keep users not get lost on your website. In this tutorial I go through how to implement a persisted scroll position using Hotwire Turbo.

We do this by hooking into the lifecycle events of Hotwire Turbo, then cache the current scroll position of each element we want to persist.

<!--
src/_components/navbar.liquid

We added the "data-turbo-permanent" attribute to this element, along with a unique ID.
-->
<nav class="navbar__nav" data-turbo-permanent id="navbar">
  {% for i in (1..10) %}
    <ul>
      <li>Item {{i}}</li>
      <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/about/">About</a></li>
        <li><a href="/posts/">Posts</a></li>
      </ul>
    </ul>
  {% endfor %}
</nav>
Enter fullscreen mode Exit fullscreen mode
// frontend/javascript/turbo-scroll.js
// This JavaScript saves the scroll position of each element with the "data-turbo-permanent" attribute.
// When the next page is renders, we restore the scroll position.
(function(){
  var scrollPositions = {};

  addEventListener("turbo:before-render", function(){
    document.querySelectorAll("[data-turbo-permanent]").forEach(function(element){ 
      scrollPositions[element.id] = element.scrollTop;
    });
  });

  addEventListener("turbo:render", function(){
    document.querySelectorAll("[data-turbo-permanent]").forEach(function(element){ 
      element.scrollTop = scrollPositions[element.id];
    });
  });
})();
Enter fullscreen mode Exit fullscreen mode

Top comments (0)