How to implement View Transition API in Turbo

I know this feature (View Transition API) is super soon to talk about, but has anyone successfully implemented transition view api with turbo?

I was trying to initiate (document.startViewTransition) at turbo:before-render event, which worked, but I experienced missing <a> tags and forms, so I think Chrome screenshoted new page when turbo was trying inject functionality to all links and forms?

I turned off cache preview for each html view to make it work

addEventListener("turbo:before-render", (event) => {

            event.preventDefault()

            document.startViewTransition(() => {
                event.detail.resume();                
            })
        })

This works, except links and forms as I mentioned.

1 Like

GitHub - domchristie/turn: 📖 Animate page transitions in Turbo Drive apps has experimental support for View Transitions, although I’ve not experienced missing links/forms
Try the examples on: Turn: Animate Page Transitions in Turbo Drive Apps

Getting the screenshot timing right and avoiding post-preview renders can be tricky. You’ll also need to be wary of the time it takes for the View Transition API to take the screenshot before calling the updateDOM callback.

Turn pauses rendering until the screenshot has been taken i.e. the callback has called. The callback returns a promise that resolves on turbo:render

1 Like

Okay, I was able to tweak my code a little bit more and wait for turbo:render event. After that, my problems with not registering some parts of the html went away. Hope it’ll help someone


        document.addEventListener("turbo:before-render", async (event) => {
            
            let fn = null

            event.preventDefault()

            document.startViewTransition(() => {
                event.detail.resume()

                const promise = new Promise((resolve, reject) => {
                    
                    fn = (event) => {
                        resolve()
                    }

                    document.addEventListener('turbo:render', fn)
                })

                promise.finally(() => {
                    document.removeEventListener('turbo:render', fn)
                })
            
                return promise
            })
    
        })
1 Like