Skip to content

Commit

Permalink
Document Type information for Custom Events
Browse files Browse the repository at this point in the history
It appears that the team's [official stance][] is that documentation for
the package's Custom Events should reside on a consumer-facing website.

The documentation for Custom Events already exists, but doesn't provide
particulars for the shapes of the most of the `event.details` objects.

This commit brings more structure to the page, namely:

* groups events by their source
* promotes event names to deeply-linkable headings
* adds HTML tables to describe each event's `event.detail` properties,
  along with type information

[official stance]: hotwired/turbo#984 (comment)
  • Loading branch information
seanpdoyle committed Sep 13, 2023
1 parent 6a00875 commit a45d647
Showing 1 changed file with 191 additions and 19 deletions.
210 changes: 191 additions & 19 deletions _source/reference/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,212 @@ description: "A reference of everything you can do with Turbo Events."

# Events

Turbo emits events that allow you to track the navigation lifecycle and respond to page loading. Except where noted, Turbo fires events on the `document.documentElement` object (i.e., the `<html>` element).
Turbo emits a variety of [Custom Events][] types, dispatched from the following
sources:

(Note that when using jQuery, the data on the event must be accessed as `$event.originalEvent.detail`.)
* [Document](#document)
* [Forms](#forms)
* [Frames](#frames)
* [Streams](#streams)
* [HTTP Requests](#http-requests)

* `turbo:click` fires when you click a Turbo-enabled link. The clicked element is the event target. Access the requested location with `event.detail.url`. Cancel this event to let the click fall through to the browser as normal navigation.
When using jQuery, the data on the event must be accessed as `$event.originalEvent.detail`.

* `turbo:before-visit` fires before visiting a location, except when navigating by history. Access the requested location with `event.detail.url`. Cancel this event to prevent navigation.
[Custom Events]: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent

* `turbo:visit` fires immediately after a visit starts. Access the requested location with `event.detail.url` and action with `event.detail.action`.
## Document

* `turbo:submit-start` fires during a form submission. Access the `FormSubmission` object with `event.detail.formSubmission`. Abort form submission (e.g. after validation failure) with `event.detail.formSubmission.stop()`. (use `event.originalEvent.detail.formSubmission.stop()` if you're using jQuery).
Turbo Drive emits events that allow you to track the navigation life cycle and respond to page loading. Except where noted, the following events fire on the `document.documentElement` object (i.e., the `<html>` element).

* `turbo:before-fetch-request` fires before Turbo issues a network request to fetch the page. Access the requested location with `event.detail.url` and the fetch options object with `event.detail.fetchOptions`. This event fires on the respective element (turbo-frame or form element) which triggers it and can be accessed with `event.target` property. Request can be canceled and continued with `event.detail.resume` (see [Pausing Requests](/handbook/drive#pausing-requests)).
### `turbo:click`

* `turbo:before-fetch-response` fires after the network request completes. Access the fetch options object with `event.detail`. This event fires on the respective element (turbo-frame or form element) which triggers it and can be accessed with `event.target` property.
Fires when you click a Turbo-enabled link. The clicked element is the event target. Access the requested location with `event.detail.url`. Cancel this event to let the click fall through to the browser as normal navigation.

* `turbo:submit-end` fires after the form submission-initiated network request completes. Access the `FormSubmission` object with `event.detail.formSubmission` along with `FormSubmissionResult` properties included within `event.detail`.
| `event.detail` property | Type | Description
|---------------------------|-------------------|------------
| `url` | `string` | the requested location
| `originalEvent` | [MouseEvent][] | the original [`click` event]

* `turbo:before-cache` fires before Turbo saves the current page to cache.
[`click` event]: https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event
[MouseEvent]: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent

* `turbo:before-render` fires before rendering the page. Access the new `<body>` element with `event.detail.newBody`. Rendering can be canceled and continued with `event.detail.resume` (see [Pausing Rendering](/handbook/drive#pausing-rendering)). Customize how Turbo Drive renders the response by overriding the `event.detail.render` function (see [Custom Rendering](/handbook/drive#custom-rendering)).
### `turbo:before-visit`

* `turbo:before-stream-render` fires before rendering a Turbo Stream page update. Access the new `<turbo-stream>` element with `event.detail.newStream`. Customize the element's behavior by overriding the `event.detail.render` function (see [Custom Actions](/handbook/streams#custom-actions)).
Fires before visiting a location, except when navigating by history. Access the requested location with `event.detail.url`. Cancel this event to prevent navigation.

* `turbo:render` fires after Turbo renders the page. This event fires twice during an application visit to a cached location: once after rendering the cached version, and again after rendering the fresh version.
| `event.detail` property | Type | Description
|---------------------------|-------------------|------------
| `url` | `string` | the requested location

* `turbo:load` fires once after the initial page load, and again after every Turbo visit. Access visit timing metrics with the `event.detail.timing` object.
### `turbo:visit`

* `turbo:before-frame-render` fires before rendering the `<turbo-frame>` element. Access the new `<turbo-frame>` element with `event.detail.newFrame`. Rendering can be canceled and continued with `event.detail.resume` (see [Pausing Rendering](/handbook/frame#pausing-rendering)). Customize how Turbo Drive renders the response by overriding the `event.detail.render` function (see [Custom Rendering](/handbook/frames#custom-rendering)).
Fires immediately after a visit starts. Access the requested location with `event.detail.url` and action with `event.detail.action`.

* `turbo:frame-render` fires right after a `<turbo-frame>` element renders its view. The specific `<turbo-frame>` element is the event target. Access the `FetchResponse` object with `event.detail.fetchResponse` property.
| `event.detail` property | Type | Description
|---------------------------|---------------------------------------|------------
| `url` | `string` | the requested location
| `action` | `"advance" \| "replace" \| "restore"` | the visit's [Action][]

* `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.
[Action]: /handbook/drive#page-navigation-basics

* `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:before-cache`

* `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.
Fires before Turbo saves the current page to cache.

Instances of `turbo:before-cache` events do not have an `event.detail` property.

### `turbo:before-render`

Fires before rendering the page. Access the new `<body>` element with `event.detail.newBody`. Rendering can be canceled and continued with `event.detail.resume` (see [Pausing Rendering](/handbook/drive#pausing-rendering)). Customize how Turbo Drive renders the response by overriding the `event.detail.render` function (see [Custom Rendering](/handbook/drive#custom-rendering)).

| `event.detail` property | Type | Description
|---------------------------|-----------------------------------|------------
| `newBody` | [HTMLBodyElement][] | the new `<body>` element that will replace the document's current `<body>` element
| `isPreview` | `boolean` | whether or not the render is a [preview][] of a cached page
| `resume` | `(value?: any) => void` | called when [Pausing Requests][]
| `render` | `(currentBody, newBody) => void` | override to [Customize Rendering](/handbook/drive#custom-rendering)

[HTMLBodyElement]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLBodyElement
[preview]: /handbook/building#understanding-caching

### `turbo:render`

Fires after Turbo renders the page. This event fires twice during an application visit to a cached location: once after rendering the cached version, and again after rendering the fresh version.

| `event.detail` property | Type | Description
|---------------------------|-----------|------------
| `isPreview` | `boolean` | whether or not the render is a [preview][] of a cached page

### `turbo:load`

Fires once after the initial page load, and again after every Turbo visit.

| `event.detail` property | Type | Description
|---------------------------|-----------|------------
| `url` | `string` | the requested location
| `timing.visitStart` | `number` | timestamp at the start of the Visit
| `timing.requestStart` | `number` | timestamp at the start of the HTTP request for the next page
| `timing.requestEnd` | `number` | timestamp at the end of the HTTP request for the next page
| `timing.visitEnd` | `number` | timestamp at the end of the Visit

## Forms

Turbo Drive emits events during submission, redirection, and submission failure. The following events fire on the `<form>` element during submission.

### `turbo:submit-start`

Fires during a form submission. Access the `FormSubmission` object with `event.detail.formSubmission`. Abort form submission (e.g. after validation failure) with `event.detail.formSubmission.stop()`. Use `event.originalEvent.detail.formSubmission.stop()` if you're using jQuery.

| `event.detail` property | Type | Description
|---------------------------|-------------------------------------------|------------
| `formSubmission` | `FormSubmission` | the `<form>` element submission

### `turbo:submit-end`

Fires after the form submission-initiated network request completes. Access the `FormSubmission` object with `event.detail.formSubmission` along with `FormSubmissionResult` properties included within `event.detail`.

| `event.detail` property | Type | Description
|---------------------------|---------------------------|------------
| `success` | `boolean` | a `boolean` representing the request's success
| `fetchResponse` | `FetchResponse \| null` | present when `success: true`, `null` when `success: false`
| `error` | [Error][] or `null` | `null` when `success: true`, present when `success: false`

[Error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors

## Frames

Turbo Frames emit events during their navigation life cycle. The following events fire on the `<turbo-frame>` element.

### `turbo:before-frame-render`

Fires before rendering the `<turbo-frame>` element. Access the new `<turbo-frame>` element with `event.detail.newFrame`. Rendering can be canceled and continued with `event.detail.resume` (see [Pausing Rendering](/handbook/frame#pausing-rendering)). Customize how Turbo Drive renders the response by overriding the `event.detail.render` function (see [Custom Rendering](/handbook/frames#custom-rendering)).

| `event.detail` property | Type | Description
|---------------------------|-----------------------------------|------------
| `newFrame` | `FrameElement` | the new `<turbo-frame>` element that will replace the current `<turbo-frame>` element
| `resume` | `(value?: any) => void` | called when [Pausing Requests][]
| `render` | `(currentFrame, newFrame) => void`| override to [Customize Rendering](/handbook/drive#custom-rendering)

### `turbo:frame-render`

Fires right after a `<turbo-frame>` element renders its view. The specific `<turbo-frame>` element is the event target. Access the `FetchResponse` object with `event.detail.fetchResponse` property.

| `event.detail` property | Type | Description
|---------------------------|-----------------------------------|------------
| `fetchResponse` | `FetchResponse` | the HTTP request's response

### `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.

Instances of `turbo:frame-load` events do not have an `event.detail` property.

### `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][] instance with `event.detail.response`, and perform a visit by calling `event.detail.visit(...)`.

| `event.detail` property | Type | Description
|---------------------------|-------------------------------------------|------------
| `response` | [Response][] | the HTTP response for the request initiated by a `<turbo-frame>` element
| `visit` | `async (location, visitOptions) => void` | a convenience function to initiate a page-wide navigation

[Response]: https://developer.mozilla.org/en-US/docs/Web/API/Response

## Streams

Turbo Streams emit events during their life cycle. The following events fire on the `<turbo-stream>` element.

### `turbo:before-stream-render`

Fires before rendering a Turbo Stream page update. Access the new `<turbo-stream>` element with `event.detail.newStream`. Customize the element's behavior by overriding the `event.detail.render` function (see [Custom Actions][]).

| `event.detail` property | Type | Description
|---------------------------|-----------------------------------|------------
| `newStream` | `StreamElement` | the new `<body>` element that will replace the document's current `<body>` element
| `render` | `async (currentElement) => void` | override to define [Custom Actions][]

[Custom Actions]: /handbook/streams#custom-actions

## HTTP Requests

Turbo emits events when fetching content over HTTP. Depending on the what
initiated the request, the events could fire on:

* a `<turbo-frame>` during its navigation
* a `<form>` during its submission
* the `<html>` element during a page-wide Turbo Visit

### `turbo:before-fetch-request`

Fires before Turbo issues a network request to fetch the page. Access the requested location with `event.detail.url` and the fetch options object with `event.detail.fetchOptions`. This event fires on the respective element (`<turbo-frame>` or `<form>` element) which triggers it and can be accessed with `event.target` property. Request can be canceled and continued with `event.detail.resume` (see [Pausing Requests][]).

| `event.detail` property | Type | Description
|---------------------------|-----------------------------------|------------
| `fetchOptions` | [RequestInit][] | the `options` used to construct the [Request][]
| `url` | [URL][] | the request's location
| `resume` | `(value?: any) => void` callback | called when [Pausing Requests][]

[RequestInit]: https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options
[Request]: https://developer.mozilla.org/en-US/docs/Web/API/Request/Request
[URL]: https://developer.mozilla.org/en-US/docs/Web/API/URLm
[Pausing Requests]: /handbook/drive#pausing-requests

### `turbo:before-fetch-response`

Fires after the network request completes. Access the fetch options object with `event.detail`. This event fires on the respective element (`<turbo-frame>` or `<form>` element) which triggers it and can be accessed with `event.target` property.

| `event.detail` property | Type | Description
|---------------------------|---------------------------|------------
| `fetchResponse` | `FetchResponse` | the HTTP request's response


### `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.

| `event.detail` property | Type | Description
|---------------------------|-------------------|------------
| `request` | `FetchRequest` | The HTTP request that failed
| `error` | [Error][] | provides the cause of the failure

[Error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors

0 comments on commit a45d647

Please sign in to comment.