Lesson 2 — Enabling Turbo Morph
The meta tags
Turbo Morph is enabled per-page via two meta tags in the <head>:
|
|
turbo-refresh-method: morph tells Turbo to diff and patch instead of
replacing the body. turbo-refresh-scroll: preserve keeps the page’s
scroll position across refreshes — without this the page jumps to the
top after every morph.
Adding meta tags in Phlex
The turbo-rails gem provides turbo_refreshes_with as a helper, but
it uses content_for :head internally — a Rails ERB mechanism that
doesn’t translate to Phlex. In Phlex you add the meta tags directly in
the layout’s <head>:
|
|
This enables morphing globally — every page in the app will morph on
refresh. That’s the right default. If a specific page has issues with
morphing (unusual JavaScript initialisation, third-party widgets that
don’t survive DOM patching), you can disable it per-page by overriding
turbo-refresh-method to replace — but that’s an edge case, not the
norm.
How morph triggers
Morphing happens when Turbo detects a page refresh — a redirect back to the same URL. The controller stays completely conventional:
|
|
When redirect_to boards_path fires and the user is already on
boards_path, Turbo intercepts the redirect, fetches the new HTML, and
morphs the DOM. The new board appears in the list without a flash, a
scroll jump, or any explicit wiring.
If the redirect goes to a different URL, Turbo Drive handles it normally — morphing only applies to same-URL refreshes.
Protecting elements from morphing
Sometimes you want an element to survive a morph untouched — an open
dropdown, an expanded accordion, a search input that the user is
actively typing in. Mark it with data-turbo-permanent:
|
|
The element must have a stable id — idiomorph uses it to match
elements across the old and new DOM. Without a unique id,
data-turbo-permanent has no effect.
This is particularly relevant for our ToastContainer — toasts that
are mid-display shouldn’t be wiped by a morph:
|
|