DEV Community

Mike Rogers ✈️
Mike Rogers ✈️

Posted on

9 2

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

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay