Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document missing frame behaviour #129

Merged
merged 5 commits into from
Mar 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion _source/handbook/03_frames.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ This page now works in both its minimized form, where only the `div` with the in

Note that the `<turbo-frame>` on `/emails/set_aside` does not contain a `src` attribute. That attribute is only added to the frame that needs to lazily load the content, not to the rendered frame that provides the content.

During navigation, a Frame will set `[aria-busy="true"]` on the `<turbo-frame>` element when fetching the new contents. When the navigation completes, the Frame will remove the `[aria-busy]` attribute. When navigating the `<turbo-frame>` through a `<form>` submission, Turbo will toggle the `[aria-busy="true"]` attribute in tandem with the Frame's.
During navigation, a Frame will set `[aria-busy="true"]` on the `<turbo-frame>` element when fetching the new contents. When the navigation completes, the Frame will remove the `[aria-busy]` attribute. When navigating the `<turbo-frame>` through a `<form>` submission, Turbo will toggle the Form's `[aria-busy="true"]` attribute in tandem with the Frame's.

After navigation finishes, a Frame will set the `[complete]` attribute on the
`<turbo-frame>` element.
Expand Down Expand Up @@ -209,6 +209,40 @@ any other state derived from the URL path and search parameters.
[Visit]: /handbook/drive#page-navigation-basics
[advance]: /handbook/drive#application-visits

## "Breaking out" from a Frame

In most cases, requests that originate from a `<turbo-frame>` are expected to fetch content for that frame (or for
another part of the page, depending on the use of the `target` or `data-turbo-frame` attributes). This means the
response should always contain the expected `<turbo-frame>` element. If a response is missing the `<turbo-frame>`
element that Turbo expects, it's considered an error; when it happens Turbo will write an informational message into the
frame, and throw an exception.

In certain, specific cases, you might want the response to a `<turbo-frame>` request to be treated as a new, full-page
navigation instead, effectively "breaking out" of the frame. The classic example of this is when a lost or expired
session causes an application to redirect to a login page. In this case, it's better for Turbo to display that login
page rather than treat it as an error.

The simplest way to achieve this is to specify that the login page requires a full-page reload, by including the
[`turbo-visit-control`][meta] meta tag:

```html
<head>
<meta name="turbo-visit-control" content="reload">
...
</head>
```

If you're using Turbo Rails, you can use the `turbo_page_requires_reload` helper to accomplish the same thing.

Pages that specify `turbo-visit=control` `reload` will always result in a full-page navigation, even if the request
originated from inside a frame.

If your application needs to handle missing frames in some other way, you can intercept the
[`turbo:frame-missing`][events] event to, for example, transform the response or perform a visit to another location.

[meta]: /reference/attributes#meta-tags
[events]: /reference/events

## Anti-Forgery Support (CSRF)

Turbo provides [CSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery) protection by checking the DOM for the existence of a `<meta>` tag with a `name` value of either `csrf-param` or `csrf-token`. For example:
Expand Down
2 changes: 1 addition & 1 deletion _source/reference/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ The following attributes are automatically added by Turbo and are useful to dete
The following `meta` elements, added to the `head`, can be used to customize caching and Visit behavior.

* `<meta name="turbo-cache-control">` to [opt out of caching](/handbook/building#opting-out-of-caching).
* `<meta name="turbo-visit-control" content="reload">` will perform a full page reload.
* `<meta name="turbo-visit-control" content="reload">` will perform a full page reload whenever Turbo navigates to the page, including when the request originates from a `<turbo-frame>`.
* `<meta name="turbo-root">` to [scope Turbo Drive to a particular root location](/handbook/drive#setting-a-root-location).
2 changes: 1 addition & 1 deletion _source/reference/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ Turbo emits events that allow you to track the navigation lifecycle and respond

* `turbo:frame-load` fires when a `<turbo-frame>` element is navigated and finishes loading (fires after `turbo:frame-render`). The specific `<turbo-frame>` element is the event target.

* `turbo:frame-missing` fires when a navigated `<turbo-frame>` element is unable to update its contents from a `<turbo-frame>` element in the response with a matching `[id]` attribute. After dispatching the event, Turbo transforms the response into a Visit and navigates the page. Cancel the event to prevent navigation. Access the request's [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) instance with `event.detail.response`.
* `turbo:frame-missing` fires when the response to a `<turbo-frame>` element request does not contain a matching `<turbo-frame>` element. By default, Turbo writes an informational message into the frame and throws an exception. Cancel this event to override this handling. You can access the [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) instance with `event.detail.response`, and perform a visit by calling `event.detail.visit(...)`.

* `turbo:fetch-request-error` fires when a form or frame fetch request fails due to network errors. This event fires on the respective element (turbo-frame or form element) which triggers it and can be accessed with `event.target` property. This event can be canceled.