From 0b2c287083c91402d44fd3075cc66bc1d8d8ee6e Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Wed, 7 Feb 2024 11:17:44 +0100 Subject: [PATCH] Document page refreshes with morphing (#160) --- _source/handbook/03_page_refreshes.md | 82 +++++++++++++++++++ .../handbook/{03_frames.md => 04_frames.md} | 0 .../handbook/{04_streams.md => 05_streams.md} | 0 .../handbook/{05_native.md => 06_native.md} | 0 .../{06_building.md => 07_building.md} | 0 .../{07_installing.md => 08_installing.md} | 0 _source/reference/attributes.md | 4 +- _source/reference/frames.md | 8 ++ 8 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 _source/handbook/03_page_refreshes.md rename _source/handbook/{03_frames.md => 04_frames.md} (100%) rename _source/handbook/{04_streams.md => 05_streams.md} (100%) rename _source/handbook/{05_native.md => 06_native.md} (100%) rename _source/handbook/{06_building.md => 07_building.md} (100%) rename _source/handbook/{07_installing.md => 08_installing.md} (100%) diff --git a/_source/handbook/03_page_refreshes.md b/_source/handbook/03_page_refreshes.md new file mode 100644 index 0000000..74daa71 --- /dev/null +++ b/_source/handbook/03_page_refreshes.md @@ -0,0 +1,82 @@ +--- +permalink: /handbook/page_refreshes.html +description: "Turbo can perform smooth page refreshes with morphing and scroll preservation." +--- + +# Smooth page refreshes with morphing + +[Turbo Drive](/handbook/drive.html) makes navigation faster by avoiding full-page reloads. But there is a scenario where Turbo can raise the fidelity bar further: loading the current page again (page refresh). + +A typical scenario for page refreshes is submitting a form and getting redirected back. In such scenarios, sensations significantly improve if only the changed contents get updated instead of replacing the `` of the page. Turbo can do this on your behalf with morphing and scroll preservation. + +${toc} + +## Morphing + +You can configure how Turbo handles page refresh with a `` in the page's head. + +```html + + ... + + +``` + +The possible values are `morph` or `replace` (the default). When it is `morph,` when a page refresh happens, instead of replacing the page's `,` Turbo will only update the DOM elements that have changed, keeping the rest untouched. This approach delivers better sensations because it keeps the screen state. + +Under the hood, Turbo uses the fantastic [idiomorph library](https://github.com/bigskysoftware/idiomorph). + +## Scroll preservation + +You can configure how Turbo handles scrolling with a `` in the page's head. + +```html + + ... + + +``` + +The possible values are `preserve` or `reset` (the default). When it is `preserve`, when a page refresh happens, Turbo will keep the page's vertical and horizontal scroll. + +## Exclude sections from morphing + +Sometimes, you want to ignore certain elements while morphing. For example, you might have a popover that you want to keep open when the page refreshes. You can flag such elements with `data-turbo-permanent`, and Turbo won't attempt to morph them. + +```html +
...
+``` + +## Turbo frames + +You can use [turbo frames](/handbook/frames.html) to define regions in your screen that will get reloaded using morphing when a page refresh happens. To do so, you must flag those frames with `refresh="morph"`. + +```html + + ... + +``` + +With this mechanism, you can load additional content that didn't arrive in the initial page load (e.g., pagination). When a page refresh happens, Turbo won't remove the frame contents; instead, it will reload the turbo frame and render its contents with morphing. + +## Broadcasting page refreshes + +There is a new [turbo stream action](/handbook/streams.html) called `refresh` that will trigger a page refresh: + +```html + +``` + +Server-side frameworks can leverage these streams to offer a simple but powerful broadcasting model: the server broadcasts a single general signal, and pages smoothly refresh with morphing. + +You can see how the [`turbo-rails`](https://github.com/hotwired/turbo-rails) gem does it for Rails: + +```ruby +# In the model +class Calendar < ApplicationRecord + broadcasts_refreshes +end + +# View +turbo_stream_from @calendar +``` diff --git a/_source/handbook/03_frames.md b/_source/handbook/04_frames.md similarity index 100% rename from _source/handbook/03_frames.md rename to _source/handbook/04_frames.md diff --git a/_source/handbook/04_streams.md b/_source/handbook/05_streams.md similarity index 100% rename from _source/handbook/04_streams.md rename to _source/handbook/05_streams.md diff --git a/_source/handbook/05_native.md b/_source/handbook/06_native.md similarity index 100% rename from _source/handbook/05_native.md rename to _source/handbook/06_native.md diff --git a/_source/handbook/06_building.md b/_source/handbook/07_building.md similarity index 100% rename from _source/handbook/06_building.md rename to _source/handbook/07_building.md diff --git a/_source/handbook/07_installing.md b/_source/handbook/08_installing.md similarity index 100% rename from _source/handbook/07_installing.md rename to _source/handbook/08_installing.md diff --git a/_source/reference/attributes.md b/_source/reference/attributes.md index 9034a7b..1a6bf4b 100644 --- a/_source/reference/attributes.md +++ b/_source/reference/attributes.md @@ -15,7 +15,7 @@ The following data attributes can be applied to elements to customize Turbo's be * `data-turbo-track="reload"` tracks the element's HTML and performs a full page reload when it changes. Typically used to [keep `script` and CSS `link` elements up-to-date](/handbook/drive#reloading-when-assets-change). * `data-turbo-frame` identifies the Turbo Frame to navigate. Refer to the [Frames documentation](/reference/frames) for further details. * `data-turbo-action` customizes the [Visit](/handbook/drive#page-navigation-basics) action. Valid values are `replace` or `advance`. Can also be used with Turbo Frames to [promote frame navigations to page visits](/handbook/frames#promoting-a-frame-navigation-to-a-page-visit). -* `data-turbo-permanent` [persists the element between page loads](/handbook/building#persisting-elements-across-page-loads). The element must have a unique `id` attribute. +* `data-turbo-permanent` [persists the element between page loads](/handbook/building#persisting-elements-across-page-loads). The element must have a unique `id` attribute. It also serves to exclude elements from being morphed when using [page refreshes with morphing](/handbook/page_refreshes.html) * `data-turbo-temporary` removes the element before the document is cached, preventing it from reappearing when restored. * `data-turbo-eval="false"` prevents inline `script` elements from being re-evaluated on Visits. * `data-turbo-method` changes the link request type from the default `GET`. Ideally, non-`GET` requests should be triggered with forms, but `data-turbo-method` might be useful where a form is not possible. @@ -38,3 +38,5 @@ The following `meta` elements, added to the `head`, can be used to customize cac * `` to [opt out of caching](/handbook/building#opting-out-of-caching). * `` will perform a full page reload whenever Turbo navigates to the page, including when the request originates from a ``. * `` to [scope Turbo Drive to a particular root location](/handbook/drive#setting-a-root-location). +* `` will configure [page refreshes with morphing](/handbook/page_refreshes.html). +* `` will enable [scroll preservation during page refreshes](/handbook/page_refreshes.html). diff --git a/_source/reference/frames.md b/_source/reference/frames.md index d060083..9234d18 100644 --- a/_source/reference/frames.md +++ b/_source/reference/frames.md @@ -87,6 +87,14 @@ Like an eager-loaded frame, but the content is not loaded from `src` until the f ``` +## Frame that will get reloaded with morphing during page refreshes + +```html + + ... + +``` + # Attributes, properties, and functions The `` element is a [custom element][] with its own set of HTML