Closed hjhart closed 3 months ago
You have to intercept navigations to external links and create a separate WebView to show them. WebView from Turbo is only intended to be used with turbo.js itself.
Thanks @MichalSznajder !
I already have some code doing that here:
interface NavDestination : TurboNavDestination {
override fun shouldNavigateTo(newLocation: String): Boolean {
Log.d("Navigation", "Navigation to ${newLocation} from ${location}")
return when (isNavigable(newLocation)) {
true -> true
else -> {
launchCustomTab(newLocation)
false
}
}
}
private fun isNavigable(location: String): Boolean {
return location.startsWith(BuildConfig.BASE_APP_URL)
}
}
But the logging (Navigation to ${newLocation} from ${location}") only shows up on the first link.
So it shows up for my internal link, returns true, and continues within the WebView with turbo.js. However, it does not log the above after the redirect. So, that mechanism fails here. It's very possible I'm intercepting the requests at the wrong point in code, but if not, this is more internal to the turbo-android
codebase than I've dug into.
I think we're getting closer. I'll keep looking through the docs to better understand if I'm intercepting the request properly.
I think I've verified that this is a bug in turbo-android
. I've added this commit to a fork of the demo repository:
https://github.com/hjhart/turbo-native-demo/commit/767139cdc09d6c4181dd357860038b39ab65f742
You can see how the external links work just fine, but a redirect to an external link does now. See the video below, running against a local server and using the default turbo-android demo code.
https://github.com/hotwired/turbo-android/assets/547981/201cd83e-c7c4-4549-9257-3f7ebfcaa532
This is what shows up in LogCat at the time:
2024-03-27 13:50:28.499 18141-18380 TurboLog dev.hotwire.turbo.demo D visitProposedToLocation ........... [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, options: TurboVisitOptions(action=ADVANCE, snapshotHTML=null, response=null)]
2024-03-27 13:50:28.506 18141-18141 TurboLog dev.hotwire.turbo.demo D shouldNavigateToLocation .......... [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, shouldNavigate: true, currentFragment: WebHomeFragment]
2024-03-27 13:50:28.511 18141-18141 TurboLog dev.hotwire.turbo.demo D navigate .......................... [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, options: TurboVisitOptions(action=ADVANCE, snapshotHTML=null, response=null), currentContext: DEFAULT, newContext: DEFAULT, presentation: PUSH, currentFragment: WebHomeFragment]
2024-03-27 13:50:28.511 18141-18141 TurboLog dev.hotwire.turbo.demo D navigateWithinContext ............. [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, presentation: PUSH, currentFragment: WebHomeFragment]
2024-03-27 13:50:28.547 18141-18141 TurboLog dev.hotwire.turbo.demo D navigateToLocation ................ [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, uri: turbo://fragment/web, currentFragment: WebHomeFragment]
2024-03-27 13:50:28.564 18141-18141 ImeTracker dev.hotwire.turbo.demo I dev.hotwire.turbo.demo:d0f1ad: onRequestHide at ORIGIN_CLIENT_HIDE_SOFT_INPUT reason HIDE_SOFT_INPUT
2024-03-27 13:50:28.565 18141-18141 StradaLog dev.hotwire.turbo.demo D bridgeDestinationDidStop .......... [https://506f8e14c2c2.ngrok.app]
2024-03-27 13:50:28.565 18141-18141 TurboLog dev.hotwire.turbo.demo D fragment.onStop ................... [session: main, location: https://506f8e14c2c2.ngrok.app, fragment: WebHomeFragment]
2024-03-27 13:50:28.583 18141-18141 TurboLog dev.hotwire.turbo.demo D fragment.onViewCreated ............ [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, fragment: WebFragment]
2024-03-27 13:50:28.588 18141-18141 TurboLog dev.hotwire.turbo.demo D fragment.onStart .................. [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, fragment: WebFragment]
2024-03-27 13:50:28.590 18141-18141 StradaLog dev.hotwire.turbo.demo D bridgeDestinationDidStart ......... [https://506f8e14c2c2.ngrok.app/follow-external-redirect]
2024-03-27 13:50:28.610 18141-18141 TurboLog dev.hotwire.turbo.demo D visitLocation ..................... [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, options: TurboVisitOptions(action=ADVANCE, snapshotHTML=null, response=null), restorationIdentifier: ]
2024-03-27 13:50:28.647 18141-18380 TurboLog dev.hotwire.turbo.demo D visitStarted ...................... [session: main, location: https://506f8e14c2c2.ngrok.app/follow-external-redirect, visitIdentifier: 094d240b-cbb3-459c-9c78-73bd5400bb5b, visitHasCachedSnapshot: false, visitIsPageRefresh: false]
2024-03-27 13:50:28.650 18141-18380 TurboLog dev.hotwire.turbo.demo D visitRequestStarted ............... [session: main, visitIdentifier: 094d240b-cbb3-459c-9c78-73bd5400bb5b]
2024-03-27 13:50:28.741 18141-18141 StradaLog dev.hotwire.turbo.demo D bridgeDestinationDidDestroy ....... [https://506f8e14c2c2.ngrok.app]
2024-03-27 13:50:28.811 18141-18141 chromium dev.hotwire.turbo.demo I [INFO:CONSOLE(0)] "Access to fetch at 'https://turbo.hotwired.dev/' (redirected from 'https://506f8e14c2c2.ngrok.app/follow-external-redirect') from origin 'https://506f8e14c2c2.ngrok.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.", source: https://506f8e14c2c2.ngrok.app/follow-external-redirect (0)
2024-03-27 13:50:28.811 18141-18380 TurboLog dev.hotwire.turbo.demo D visitRequestFailedWithStatusCode .. [session: main, visitIdentifier: 094d240b-cbb3-459c-9c78-73bd5400bb5b, visitHasCachedSnapshot: false, error: UnknownError(statusCode=0, reasonPhrase=null)]
2024-03-27 13:50:28.815 18141-18141 Compatibil...geReporter dev.hotwire.turbo.demo D Compat change id reported: 210923482; UID 10191; state: ENABLED
2024-03-27 13:50:28.841 18141-18380 TurboLog dev.hotwire.turbo.demo D visitRequestFinished .............. [session: main, visitIdentifier: 094d240b-cbb3-459c-9c78-73bd5400bb5b]
@jayohms I'm happy to take this work on, as it is blocking my companies critical path, but do you have any pointers as to what code I might want to touch before I dive into this work?
@hjhart I dug into this and it's is an issue in both turbo-android
and turbo-ios
, so we'll need fixes in both libraries. See the PR with details: #325
Due to the CORS policy in turbo.js
fetch requests, all the adapters see external redirects as request failures, but the linked PR handles the issue in a similar but different way than the default browser
adapter. Can you give it a try and see if it resolves your issue?
@jayohms, wow, that works perfectly. Thanks so much!
https://github.com/hotwired/turbo-android/assets/547981/46b22503-4ce2-4586-8db8-d6b9d64abdfe
The fix is now available in 7.1.2: https://github.com/hotwired/turbo-android/releases/tag/7.1.2
Hey @jayohms, thanks for the quick release! Does this also require an upgrade of turbo.js, or turbo-rails?
Edit: Opened up another issue https://github.com/hotwired/turbo-android/issues/327
Expected behavior:
When tapping on a link that redirects to an external site The external site should load correctly
Actual behavior:
"Error loading page" screen
Along with this in the Logcat output:
Isolating the problem further, if instead I have the original link pointing to
https://our-app.formstack.com/forms/redacted
instead ofhttp://app.android-local.dev-hellobrightline.com:3000/formstack/forms/3f76559e-bb49-4465-a7ab-ab4e75b80f29
, it works just fine. The introduction of the redirect seems to break it.I noticed the CORS error in firefox and chrome, and disabling turbo fixed the request since it stopped being a
fetch
via turbo.js. Now it's happily a link that redirects successfully. But in our turbo-android app, it is still failing.Since I don't have control over the formstack servers, I cannot modify the CORS headers successfully.
I'm going to continue to dive into this issue, but wanted to post it here for posterity, and to hopefully get some help from anyone who has encountered this issue previously.
Thanks in advance.