Skip to main content

Turbo JS

Introduction

Turbo JS (from Hotwire) enables fast, dynamic content loading without JavaScript. With Turbo Frames, you can replace parts of a page without full-page reloads, making your site more interactive.

Loading Turbo JS

To use Turbo JS, include it in your file section only on pages that need it:

{% block head %}
<script src="{{ setting.cdn.default_assets_url }}/vendor/@hotwired/turbo/dist/turbo.es2017-umd.js"></script>
{#
By default, Turbo intercepts navigation and form submissions.
To disable automatic navigation, add the following script to ensure it runs after the page loads:
#}
<script>
document.addEventListener("DOMContentLoaded", function () {
Turbo.session.drive = false;
});
</script>
{% endblock %}
<script>
document.addEventListener("DOMContentLoaded", function () {
Turbo.session.drive = false;
});
</script>

Turbo Frames

Turbo Frames allow loading specific content dynamically without a full-page refresh.

Example: Loading Content

Inside home.html, define the frame that will dynamically load content. This file is loaded when the page is accessed and acts as the main structure for your content. The example assumes leaderboards.html is created in the assets folder. The frame fetches data dynamically.

<div class="row">
{% for plugin in integrationsGetEnabledPlugins('cs2','leaderboards') %}
<div class="col-md-6">
<turbo-frame id="leaderboard{{ plugin.id }}"
src="/leaderboards/{{ plugin.link }}?turbo=leaderboards">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</turbo-frame>
</div>
{% endfor %}
</div>
SRC Attribute

The src attribute dynamically loads content from another file. You must add a GET parameter to the src with the name turbo=file-name, where file-name should be the file name without the .html extension. Example src: src="/test-turbo?turbo=leaderboards"

Turbo Frame Content

Inside assets/leaderboards.html, define the frame content:

<turbo-frame id="leaderboard{{ integration.current.id }}">
<ul>
{% for player in leaderboards.top_players %}
<li>
<span style="color: {{ player.current_rank.color }};">
{{ player.username }}
</span>
- {{ player.points }} pts
</li>
{% endfor %}
</ul>
</turbo-frame>

Frame ID Matching

Ensure the id in <turbo-frame> is identical in both files, otherwise Turbo will not load the content.

Handling Navigation Inside Frames

By default, clicking links inside Turbo Frames only updates the frame's content. If you want a full-page load, add:

<a href="/profile/{{ player.steam_id }}" data-turbo="false">View Profile</a>

This prevents Turbo from intercepting the link.

More Turbo Features

  • Turbo Streams: Enables real-time updates to elements.
  • Lazy Loading: Frames can be deferred until visible.
  • Form Submission Handling: Automatically updates content without reloading.

For more details, see the official documentation:

Turbo JS Handbook