I have a Next.js app that I deploy to web, let’s say to URL https://example.com
, and also wrap with Capacitor to release to Android and iOS. To enable the autofill feature on Android, we set server.androidScheme
to https
, and server.hostname
to example.com
in capacitor config. The autofill works fine, however I realised that when I statically build my app and run it, the app renders the contents of my web deployment and completely ignoring what is bundled with the app on build time.
Please let me know if any of this is wrong but how I assume a Capacitor app works is that when I run the app, it starts a locally running server that serves the contents of the web app, and renders it on the web view. The URL of this locally running server is made up of what is in Capacitor config files, so in my case, it’s https://example.com
which is the same as my web deployment. So when the app tries to fetch the contents of the app from this local server, it fetches them from the web deployment instead, hence the local contents being ignored.
This is currently blocking an Android release because we don’t want our mobile apps to be completely in sync with our web deployments, at least without our control. Has anyone else experienced a similar issue?
It works the other way, it loads the local assets and if you try to connect to a endpoint that is only online it will 404 as it’s not there on the local assets.
Maybe you have set the server.url
to https://example.com
? that’s the only way of loading the remote assets instead of the local ones.
Hey @julio-ionic, thanks for the reply. We don’t use server.url
at all.
So you mean even if the URL’s are the same, the requests always resolve to the locally running server rather than the remote one?
yes, the should never reach the server as they are intercepted by Capacitor
Okay, thank you so much for the info. I got this behaviour when I was running a static prod build on my device through Android Studio and had the Chrome inspector attached to the app. It seems the builds we upload to Google Play internal channel don’t really have this behaviour, so I’ll just assume the interception logic somehow didn’t work for that setup and leave it at that.
I will have to revive this thread because we seem to be having this issue on prod with multiple customers complaining. Is there any possibility for this behaviour at all, maybe an edge case? I’m checking the code for WebViewLocalServer.java but haven’t found any culprits so far.
I was able to verify this by setting server.hostname
to a website completely different than my app’s web deployment URL, and seeing the contents of that different URL load into the web view. To be more specific, this happens when line 304 on Bridge.java is executed:
webView.loadUrl(appUrl);
I assume this needs to be then intercepted by the local server, but for some reason it’s not. Only when I omit server.hostname
from the config file, appUrl
resolves to https://localhost
and the app loads fine.
What version of Capacitor Android are you using today? I’m trying to repro this and am failing to do so given an arbitrary URL wanted to try and recreate like conditions.
We are using these versions:
"@capacitor/android": "6.1.1",
"@capacitor/core": "6.1.1",
"next": "14.1.0",
Yeah I dunno if I’m doing something wrong here but with just a basic:
ionic start
a basic blank angular application
npm install @capacitor/android
- add server with a hostname of www.google.com and either an androidScheme of https or http (tried both)
npm run build
npx cap sync
And then when I run the application it’s the default ionic starter blank application. From here, my thoughts are maybe it’s something specific to next that I’m not seeing in an Angular application? That’s the only difference that would remain that I see.
Is it possible to get a sample reproduction case of this from your side with just like a blank application that reproduces the issue? A github repo link or something along those lines?
We were finally able to pinpoint the exact reason why this was happening. We utilise a service worker for our builds to enable PWA capabilities. When initialised, this service worker serves the entire app before Capacitor’s local server can intercept the requests, hence why we were seeing the web deployment instead of what’s bundled with the native app. We’ll remove the service worker from our native builds, which should hopefully resolve this issue.