Release Build Loading Remote Content: Diagnosing Capacitor's server Block
0 reputation · 18 Mar 2024, 18:57 UTC
0 reputation · 18 Mar 2024, 18:57 UTC
A Capacitor app is normally expected to serve its bundled web assets from the local WebView origin, but the server block in capacitor.config can override that origin. When server.url is present, the WebView loads content from the named host rather than the packaged build — a setting documented as a live-reload aid for development, yet not inherently restricted to debug builds.
The unresolved part is where that constraint belongs. server.allowNavigation limits WebView navigation to listed hosts, but it does not govern fetch or XHR calls made by JavaScript, and defaults differ between iOS and Android. server.cleartext and androidScheme also affect the resulting origin, which in turn changes localStorage, cookies and CORS behaviour.
Because configuration is applied to native projects during npx cap sync, generated native files can drift from capacitor.config if sync is skipped or run against a different file. Option names and defaults in the server block have also changed across Capacitor majors.
server.url at the config level, the build level, or both?allowNavigation sufficient on its own, or does it need to be paired with native WebView settings per platform?34775 reputation · 18 Mar 2024, 22:07 UTC
To keep a release build from loading remote content via server.url, you must block the setting at both the configuration level (the file used for npx cap sync) and the build level (the generated native config that ends up in the app bundle). server.allowNavigation alone does not protect fetch/XHR calls; you need to pair it with platform‑specific network policies (Android Network Security Config / cleartext, iOS App Transport Security). The most reliable way to confirm the actual origin is to log window.location.origin (or a test fetch target) from a release‑signed build and read that value from Logcat or the Xcode console, while also verifying that a change to a bundled asset is reflected in the running app.
The server block is copied into the native projects during cap sync. The WebView reads the generated native config at launch, so if server.url is present in the config used for the last sync, a release build will honor it and load remote content. The block does not have a built‑in debug‑only guard; the restriction must be enforced by the developer.
server.allowNavigation only limits top‑level and iframe navigations; it does not restrict fetch, XHR, or other resource loads.server.cleartext (Android) and androidScheme/iosScheme affect the WebView origin, which in turn changes localStorage, cookies, and CORS behavior.android/app/src/main/assets/capacitor.config.json and ios/App/App/capacitor.config.json) can drift from capacitor.config if cap sync is skipped or run against a different config file.npx cap sync (or cap copy) does not contain a server.url property for the release profile. Use environment‑based config or a separate capacitor.release.json that omits the property.# Android
cat android/app/src/main/assets/capacitor.config.json
# iOS
cat ios/App/App/capacitor.config.json
server.url appears in either generated file.android:usesCleartextTraffic="false" in the manifest and add a Network Security Config that permits only HTTPS origins you trust.Info.plist with appropriate exceptions if needed.server.allowNavigation as an additional navigation allowlist, but do not rely on it alone for network security.console.log('CAPACITOR ORIGIN', window.location.origin);
// optional test fetch
fetch('/ping').then(r => r.text()).then(t => console.log('FETCH target', new URL(r.url).origin));
adb logcat | grep "CAPACITOR ORIGIN"device log.capacitor://localhost or the custom scheme you set).index.html), rebuild the release bundle, and verify the change appears in the running app; if it does not, the WebView is loading from a remote origin.To give a precise recommendation about default values for server.allowNavigation and platform network policies, I need to know: Which major version of Capacitor are you targeting (e.g., v3, v4, v5)? This changes the default navigation allowlist and the default scheme used for the WebView origin.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.