Before Cache Reset
stimeo--reset-before-cache
Tidies transient state before a page is remembered, so going back never lands mid-interaction.
Turbo remembers a page so it can show it again instantly when you go back. It also remembers the open menu, the half-typed value and the notice you never dismissed as well, so the restored page looks frozen part-way through something. This tidies that transient state away just before the page is remembered. What to tidy is declared in your markup: remove these attributes, remove these classes, reset this form, put this one field back the way it was written, hide this again. One of these on the page covers everything within its scope.
Open the details, type a value, and show the toast — then simulate the cache.
Open me
This panel is open. After the cache reset it returns to closed.
Keyboard
This component has no keyboard interactions of its own.
<%# Markup for the before-cache reset demo.
On turbo:before-cache the controller returns transient UI to its initial state so a
Back-button restore is not frozen mid-interaction. This Playground has no real Turbo
navigation, so demo.js fakes the turbo:before-cache event. Open the details, type in
the field, and show the toast — then "Simulate before-cache" resets them all. %>
<div class="reset-demo" data-controller="stimeo--reset-before-cache">
<p class="reset-demo__note"><%= t("components.reset_before_cache.demo.note") %></p>
<details class="reset-demo__details" data-reset-attr="open">
<summary><%= t("components.reset_before_cache.demo.details_summary") %></summary>
<p><%= t("components.reset_before_cache.demo.details_body") %></p>
</details>
<label class="reset-demo__field">
<span><%= t("components.reset_before_cache.demo.input_label") %></span>
<input type="text" class="demo-input" data-reset-value
placeholder="<%= t("components.reset_before_cache.demo.input_placeholder") %>">
</label>
<div class="reset-demo__toast" data-reset-demo="toast" data-reset-hidden hidden role="status">
<%= t("components.reset_before_cache.demo.toast_text") %>
</div>
<div class="reset-demo__controls">
<button type="button" class="demo-trigger" data-reset-demo="show-toast">
<%= t("components.reset_before_cache.demo.show_toast") %>
</button>
<button type="button" class="demo-trigger" data-reset-demo="simulate">
<%= t("components.reset_before_cache.demo.simulate") %>
</button>
</div>
</div>
/*
* Presentation-only styles for the before-cache reset demo.
* The library only mutates the marked elements on turbo:before-cache (removing
* attributes, restoring fields to their authored state, re-hiding, removing
* nodes); this CSS owns layout.
*/
.reset-demo {
display: flex;
flex-direction: column;
gap: 0.75rem;
max-width: 32rem;
}
.reset-demo__note {
margin: 0;
font-size: 0.85rem;
color: var(--color-text-muted);
}
.reset-demo__details {
padding: 0.6rem 0.8rem;
border: 1px solid var(--border);
border-radius: 0.5rem;
}
.reset-demo__field {
display: flex;
flex-direction: column;
gap: 0.25rem;
font-size: 0.85rem;
}
.reset-demo__toast {
padding: 0.5rem 0.75rem;
border: 1px solid var(--leaf-500);
border-radius: 0.5rem;
background: var(--leaf-50);
color: var(--leaf-500);
font-size: 0.9rem;
}
.reset-demo__toast[hidden] {
display: none;
}
.reset-demo__controls {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
// Consumer-side JS for the before-cache reset demo (demo-only).
// Real Turbo navigation fires turbo:before-cache when caching a snapshot; this
// Playground has none, so the "Simulate" button dispatches that event to show the
// reset. The "Show toast" button reveals the transient toast the reset re-hides.
const toast = document.querySelector("[data-reset-demo='toast']");
const showToast = document.querySelector("[data-reset-demo='show-toast']");
const simulate = document.querySelector("[data-reset-demo='simulate']");
if (showToast && toast) {
showToast.addEventListener("click", () => {
toast.hidden = false;
});
}
if (simulate) {
simulate.addEventListener("click", () => {
document.dispatchEvent(new Event("turbo:before-cache"));
});
}
// The controller emits this once it has reset the snapshot's transient UI.
document.addEventListener("stimeo--reset-before-cache:reset", () => {
console.log("[reset-before-cache] transient UI reset before caching");
});
These demo styles use shared design tokens (light + dark). Copy the shared styles too, then toggle data-theme on your root element for dark mode.
The data-* attributes you add to your own HTML to wire this component. Put the data-controller below on a root element, then place its targets / values / actions inside that element.
On the root element
data-controller="stimeo--reset-before-cache"
Values
| Name | Description | Attribute |
|---|---|---|
scope
|
Selector narrowing the scan to a descendant; empty scans the whole subtree. | data-stimeo--reset-before-cache-scope-value |
dispatchReset
|
Whether to emit the request event for controllers (default true). |
data-stimeo--reset-before-cache-dispatch-reset-value |
Actions
| Name | Description | Action |
|---|---|---|
reset
|
Runs the reset sweep now (also bound to turbo:before-cache internally). |
stimeo--reset-before-cache#reset |
Events
| Name | Description | Event |
|---|---|---|
reset
|
Fires after the reset sweep runs. | stimeo--reset-before-cache:reset |
request
|
Sent so individual controllers can run their own close logic. | stimeo--reset-before-cache:request |