Frames
﹟ Basic frame
Confines all navigation within the frame by expecting any followed link or form submission to return a response including a matching frame tag:
<turbo-frame id="messages">
<a href="/messages/expanded">
Show all expanded messages in this frame.
</a>
<form action="/messages">
Show response from this form within this frame.
</form>
</turbo-frame>
﹟ Eager-loaded frame
Works like the basic frame, but the content is loaded from a remote src first.
<turbo-frame id="messages" src="/messages">
Content will be replaced when /messages has been loaded.
</turbo-frame>
﹟ Lazy-loaded frame
Like an eager-loaded frame, but the content is not loaded from src until the frame is visible.
<turbo-frame id="messages" src="/messages" loading="lazy">
Content will be replaced when the frame becomes visible and /messages has been loaded.
</turbo-frame>
﹟ Frame targeting the whole page by default
<turbo-frame id="messages" target="_top">
<a href="/messages/1">
Following link will replace the whole page, not this frame.
</a>
<a href="/messages/1" data-turbo-frame="_self">
Following link will replace just this frame.
</a>
<form action="/messages">
Submitting form will replace the whole page, not this frame.
</form>
</turbo-frame>
﹟ Frame with overwritten navigation targets
<turbo-frame id="messages">
<a href="/messages/1">
Following link will replace this frame.
</a>
<a href="/messages/1" data-turbo-frame="_top">
Following link will replace the whole page, not this frame.
</a>
<form action="/messages" data-turbo-frame="navigation">
Submitting form will replace the navigation frame.
</form>
</turbo-frame>
﹟ Frame that promotes navigations to Visits
<turbo-frame id="messages" data-turbo-action="advance">
<a href="/messages?page=2">Advance history to next page</a>
<a href="/messages?page=2" data-turbo-action="replace">Replace history with next page</a>
</turbo-frame>
﹟ Frame that will get reloaded with morphing during page refreshes & when they are explicitly reloaded with .reload()
<turbo-frame id="my-frame" refresh="morph" src="/my_frame">
</turbo-frame>
Attributes, properties, and functions
The <turbo-frame> element is a custom element with its own set of HTML
attributes and JavaScript properties.
﹟ HTML Attributes
-
srcaccepts a URL or path value that controls navigation of the element -
loadinghas two valid enumerated values: “eager” and “lazy”. Whenloading="eager", changes to thesrcattribute will immediately navigate the element. Whenloading="lazy", changes to thesrcattribute will defer navigation until the element is visible in the viewport. The default value iseager. -
busyis a boolean attribute toggled to be present when a<turbo-frame>-initiated request starts, and toggled false when the request ends -
disabledis a boolean attribute that prevents any navigation when present -
targetrefers to another<turbo-frame>element by ID to be navigated when a descendant<a>is clicked. Whentarget="_top", navigate the window. -
completeis a boolean attribute whose presence or absence indicates whether or not the<turbo-frame>element has finished navigating. -
recurseallows the<turbo-frame>to load content that contains another nested frame.recurserefers to another<turbo-frame>element by ID, present in the frame’s loaded contents. This can be used when Turbo needs to extract frame content from a response that doesn’t contain the target frame directly, but contains another frame that can load the target frame.For example, imagine
/frames.htmlcontains:
<turbo-frame id="recursive" recurse="composer" src="recursive.html">
</turbo-frame>
And recursive.html contains:
<turbo-frame id="recursive">
<turbo-frame id="composer">
<a href="frames.html">Link</a>
</turbo-frame>
</turbo-frame>
When Link navigates back to frames.html, Turbo needs to find the frame with ID composer
in the response to update the current composer frame. Since there’s no such frame in
frames.html directly, Turbo finds the frame with recurse="composer", activates it to load
its src (recursive.html), then searches for and extracts the composer frame from that
loaded content to update the original frame.
autoscrollis a boolean attribute that controls whether or not to scroll a<turbo-frame>element (and its descendant<turbo-frame>elements) into view after loading. Control the scroll’s vertical alignment by setting thedata-autoscroll-blockattribute to a valid Element.scrollIntoView({ block: “…” }) value: one of"end","start","center", or"nearest". Whendata-autoscroll-blockis absent, the default value is"end". Control the scroll’s behavior by setting thedata-autoscroll-behaviorattribute to a valid Element.scrollIntoView({ behavior: “…” }) value: one of"auto", or"smooth". Whendata-autoscroll-behavioris absent, the default value is"auto".
﹟ Properties
All <turbo-frame> elements can be controlled in JavaScript environments
through instances of the FrameElement class.
-
FrameElement.srccontrols the pathname or URL to be loaded. Setting thesrcproperty will immediately navigate the element. WhenFrameElement.loadedis set to"lazy", changes to thesrcproperty will defer navigation until the element is visible in the viewport. -
FrameElement.disabledis a boolean property that controls whether or not the element will load -
FrameElement.loadingcontrols the style (either"eager"or"lazy") that the frame will loading its content. -
FrameElement.loadedreferences a Promise instance that resolves once theFrameElement’s current navigation has completed. -
FrameElement.completeis a read-only boolean property set totruewhen theFrameElementhas finished navigating andfalseotherwise. -
FrameElement.autoscrollcontrols whether or not to scroll the element into view once loaded -
FrameElement.isActiveis a read-only boolean property that indicates whether or not the frame is loaded and ready to be interacted with -
FrameElement.isPreviewis a read-only boolean property that returnstruewhen thedocumentthat contains the element is a preview.
﹟ Functions
FrameElement.reload()is a function that reloads the frame element from itssrc.