Migration from turbolinks to turbo causing blank page on older turbolinks native iOS app

Hi everyone, and thanks for taking some time to read this post!

We are migrating a rails app from Turbolinks to Turbo and it’s working pretty well so far. We also have mobile apps for iOS and Android using the new turbo native adapters which has been out for a while and working well in junction with the Turbolinks 5 rails app we currently have in production and also works well with the new Turbo rails app. However, during the migration to Turbo we came across this compatibility shim that aims to make even the old versions of the mobile apps, that still runs the turbolinks native adapter, compatible with Turbo in the backend. But what we noticed is that, even with the shim in place, the turbolinks version of the mobile apps doesn’t finish navigating from a link to a new page. The Turbolinks.visit methods from the shim script is triggered fine but something is wrong in the Turbolinks adapter code that is not handling the visit correctly. The current behavior we have today is causing the app to load the first page correctly and then if a link is clicked it will start the visit in the JS code but not reach the backend at all so a new view controller (in iOS for instance) will be put in the stack but with a blank content. If I use the Safari web inspector there’s no console errors and I can reload it and the page will appear correctly. So I’m wondering if anyone had experienced a similar behavior before and would be willing to shed some light on what might be wrong here.

I also saw this related post but it didn’t get any answers regarding the culprit and, even though supporting the old apps is not that critical, it would be nice if we could make it work.

I was able to fix the issue by removing parts of the code from the original shim javascript file which became this:

window.Turbolinks = {
  visit: Turbo.visit,

  controller: {
    isDeprecatedAdapter(adapter) {
      return typeof adapter.visitProposedToLocation !== "function";

    startVisitToLocationWithAction(location, action, restorationIdentifier) {
      window.Turbo.navigator.startVisit(location, restorationIdentifier, { action });

    get restorationIdentifier() {
      return window.Turbo.navigator.restorationIdentifier;

    get adapter() {
      return window.Turbo.navigator.adapter;

    set adapter(adapter) {
      adapter.visitProposedToLocation = function(location, options) {
        adapter.visitProposedToLocationWithAction(location, options.action);


document.addEventListener("turbo:load", function() {
  const event = new CustomEvent("turbolinks:load", { bubbles: true });

I’m not entirely sure why the removed code didn’t work for our older turbolinks native apps but from the code comments in the shim I’d guess it’s because our adapter version is not that old to need that piece. So I’d suggested anyone facing a similar issue to try to incrementally comment and uncomment some pieces there to see what works best.