Is the most important part of Turbo, despite it seems the simplest, I think it’s because frames and streams seems more spectacular. It basically avoids full-reloading of HTML page, just replacing the <body>, giving a clean sense of navigation. Intercepting usual HTTP requests and use fetch for server calls. It also manages full browser history with advance/replace/restore actions.
We can decompose its main features in 15 points:
- Page navigation basics:
- Visit (def.): Entire navigation lifecycle is: change browser history -> fetch request -> restoring a copy from cache -> rendering response -> updating scroll position.
- Types of visits are: Application (as an action of advance/replace) and restoration (as an action of restore cache page)
- You can also delete all cache with: Turbo.clearCache()
- Application Visits
- Turbo.visit(location) tries to render a preview, if exists, of the actual view. Then replaces it and add to history with history.pushState.
- If you want to replace the state of the browser-history, you can manage it by a tag <a href=”/edit” data-turbo-action=”replace”/>. Or by JavaScript: Turbo.visit(“/edit”,{action: “replace”}).
- Restoration visits: These are fired when you click on back/forward buttons in your browser or mouse.
- Canceling visits before they start: You can do it by listening the event “turbo:before-visit”. Preventing default behavior with event.preventDefault(). And finally you can check location in event.detail.url.
- Pausing rendering: You can do it by listening the event “turbo:before-render”. Preventing default behavior with event.preventDefault(). Do things you want to do. And resume rendering with event.detail.resume() function.
- Pausing requests: The same as before point but listening “turbo:before-fetch-request”.
- Links with different methods: Method fired by a link by default is GET. You can replace it: <a href=”/article/64″ turbo-data-method=”delete”>Delete article</a>.
- Disable Turbo on specific links or forms: It can be disabled for links <a href=”/articles” data-turbo=”false”>Disabled Turbo</a>. Or directly importing Turbo in JavaScript: Turbo.session.drive=false.
- Displaying progress: Drive installs a CSS Turbo progress bar by default:
- Appears when action takes longer than 500ms (you can change this time with Turbo.setProgressBarDelay()).
- To manipulate CSS appearance with class: .turbo-progress-bar.
- Also puts to true “aria-busy” attribute, and false when all action is done.
- Reloading when assets change: When an asset changes in <head> full page is reloaded. For that purpose you have to put [data-turbo-track=”reload”] and version ID in all header assets.
- Force full reload for certain pages: Include in <head> the tag: <meta name=”turbo-visit-control” content=”reload”>
- Setting root location: You can have a concrete path for your app like “/app” and all others are completely different apps. Include in <head> this: <meta name=”turbo-root” content=”/app”/>. And Turbo will be disabled in other roots.
- Form submissions:
- Form lifecycle can be manipulated through events (see Reference/Events)
- Turbo also sends a “disable” attribute to submitter (submit button)
- Events like: “turbo:submit-start”, “turbo:before-fetch-request”,…
- Redirecting after form submission: Turbo waits for 3xx redirect responses to fetch content. Except on 4xx (wrong inputs) or 5xx errors.
- Streaming after form submission:”Content-Type: text/vnd.turbo-stream.html” with content of several <turbo-stream> elements, so you can replace all of the in one action.