Tips for leveling up with a virtual DOM component

Stimulus and Turbolinks were designed to play well with one another. It’s been hinted in a couple different places that it’s possible to level up a view with a component from one of the component frameworks (Vue or React) in the places where a feature requires that degree of complexity (ex. Basecamp’s calendar). @sam or @javan, would you be willing to comment on how Basecamp approaches this scenario?

Specifically, how do you get your components to play nice with the Turbolinks cache? Is there a pattern you leverage in your Stimulus controllers and client side components?

In Vue, for example, you have to cache the element you’re mounting the component on before the component mounts so that when you go back and the JS is re-executed the element exists. Often the element doesn’t exist after the component is mounted. It’s been replaced by whatever HTML is created by the component. Chris Oliver and I created a plugin for Vue to help us solve this problem.

Can you speak to how you approach this problem in light of Stimulus and Turbolinks? Maybe in the context of the Basecamp calendar?

Basecamp’s calendar doesn’t use a separate framework / vDOM. It levelssteps up by fetching JSON and rendering client side. So I’m afraid we can’t help you from experience.

how do you get your components to play nice with the Turbolinks cache?

See Controllers disconnect method fired after Turbolinks `before-cache` method · Issue #104 · hotwired/stimulus · GitHub for a few tips / ideas.

1 Like

Hmm. Interesting! What are you using to render the JSON?

Thanks for the link! I’ll give it a read!

As a newbie, what do you mean by level up/step up ? Is there any resource where i can learn about it ?

What I’m referring to when I say “Levels/setups up” is to use a front-end JS framework like Vue or React to manage the HTML on parts of a page.

The big idea behind Stimulus and Turbolinks is to provide the experience of a single-page application while rendering views on the server. In some cases, however, you might have an interaction that would be best implemented using the tools provided by Vue or React. You don’t want your whole app to be implemented in the framework. You just want create a component on the page. Leveling up refers to using React or Vue alongside Vue and Turbolinks. Using client-side rendering is alluded to at the end of the preface of the Stimulus Handbook. Trying to better understand how to get all these technologies to play nice together was the motivation for this question. There are several gotchas that make trying to use all three of these technologies together challenging.

At this point, I’m not aware of any guides of how to do this well, which why I was asking Javan and Sam if they had any insight.

I’ve recently converted much of the DOM in my application to react (using react-rails and webpacker) and, pleasantly, it all still works as expected with stimulus and turbolinks. I’m essentially using react to simply render a more sophisticated DOM.

I’m happy to provide an example if you like, but so far it has required zero additional effort.

That’s awesome to hear! If you’re willing, I think a small sample project would be awesome to help those just getting started to see how you’ve done it.

I’ve been experimenting with initializing Vue components in Stimulus controllers. This works really well with Turbolinks. Here’s a gist with an example: https://gist.github.com/crispinheneise/c9de022dc94c16131971b64d49c0778d