capacitor: bug: service worker server.url not injecting capacitor
Bug Report
Capacitor Version
Latest Dependencies:
@capacitor/cli: 3.3.2
@capacitor/core: 3.3.2
@capacitor/android: 3.3.2
@capacitor/ios: 3.3.2
Installed Dependencies:
@capacitor/ios: not installed
@capacitor/cli: 3.3.2
@capacitor/android: 3.3.2
@capacitor/core: 3.3.2
Platform(s)
Current Behavior
Calling any native plugins when an app is served from an Angular service worker causes the plugins to fail. Using server.url to load the site on Android.

Platform ready does not help for this.
Expected Behavior
Capacitor needs to be injected when a site is served through a service worker.
Code Reproduction
app.module.ts
export function init_app(appLoadService: AppLoadService) {
return () => appLoadService.initApp();
}
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
ServiceWorkerModule.register('ngsw-worker.js', {
enabled: environment.production,
// Register the ServiceWorker as soon as the app is stable
// or after 30 seconds (whichever comes first).
registrationStrategy: 'registerWhenStable:30000',
}),
],
providers: [
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
{
provide: APP_INITIALIZER,
useFactory: init_app,
deps: [AppLoadService],
multi: true,
},
],
bootstrap: [AppComponent],
})
export class AppModule {}
app-load-service.ts
@Injectable({
providedIn: 'root',
})
export class AppLoadService {
constructor(
private device: DeviceInfo,
private platform: Platform
) {}
async initApp(): Promise<any> {
await this.platform.ready();
SplashScreen.hide(); // breaks
}
}
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 12
- Comments: 87 (11 by maintainers)
After working several hours on this I ended up with this solution working on capacitor 5. Hope this can help someone.
I am also impacted by this. Any updates on whether or not this is on the roadmap? Thanks!
Full working workaround with latest Capacitor and latest Android - compiled from ideas of @yoyo930021
Note that depending on your SW setup root file may not be called “index.html”. In that case feel free to adjust
if(request.getUrl().toString().contains("index.html"))condition above according to your app’s setup@dylanvdmerwe Thanks for the additional context, very helpful. What I’m seeing is that SWs and caching, with Capacitor, does work in some cases, so I’m trying to narrow down the exact setup that fails and what works, so we can document it if there’s no fix we can make.
For example, I’m finding Next.js + next-pwa defaults enable this to work, and that would likely to apply to a ton of Next sites which is obviously a quite popular approach! But still interested in finding a fix for your approach
For us, the usecase is the ability to switch between different SPA application builds (e.g. test/prod, or customer1/customer2) without recompiling wrapper application.
Also, more importantly - delivering app updates quickly without recompiling / updating wrapper application on app stores (for apple store new app version validation can take time, and customers want updates ASAP)
I using this answer and work for me on android with capacitor 2. https://stackoverflow.com/questions/55894716/how-to-package-a-hosted-web-app-with-ionic-capacitor/55916297#55916297
but I replace
ServiceWorkerControllertoServiceWorkerControllerCompatfor my case.Is there any permanent resolution to this issue to make service workers work with capacitor plugins on Android? It is very frustrating that my Ionic6/Angular13 app works nicely with the service worker on browser but fails to register the same on Android. When I implement the workaround suggested, service worker loads but capacitor plugins fail to load on the device. Please update when there is any resolution or workaround for this.
I am also facing same issue. I have removed the service worker from my code. Still same. Any idea?
Had this sam issue,
This worked for me. I just have to check if platform is Android, then I reloadForCapacitorInjection. Hope this helps. Thanks for all your inputs above.
`reloadForCapacitorInjection() {
}`
In next.js or SSR, It is reasonable not to cache HTML. In SPA or offline APP, we need to cache HTML.
I think a way to inject some code in HTML. Maybe can slove it.
@dylanvdmerwe I just tested iOS using app bound domains, can confirm assets are loaded from service worker, and native plugin access works just fine.
I’m not an expert with SW’s though, only using the defaults in next-pwa: https://github.com/shadowwalker/next-pwa
But all appears to be working
@yoyo930021 with that snippet it works always. App launch, reloading the app, later app launches, etc.
Want to try my sample? https://github.com/mlynch/capacitor-remote-offline-example
On Android, I am testing this right now in Capacitor v4, Chrome WebView v101, Android 13 emulator (API 33), and this is working just fine for me:
With this I am able to load a remote URL (not localhost), and have it access plugins which are correctly defined and routed to native plugin code.
Am I missing something for why this approach isn’t working for others? cc @dylanvdmerwe
im using capacitor v4 and still got the issue, non of the solutions worked for me 😦
We’re also running into this problem. The workaround with the Plugin doesn’t seem to work for us. Not sure why, and I can’t see a way to check what goes wrong.
I had to convert the kotlin code above to java, so maybe something went wrong there? although the code does get called, when I hook the android debugger to it.
The Plugin java code:
The
returnreturnsnullon a request to[domain]/sw.jsand I feel this is wrong?@Aarbel @dylanvdmerwe You must to use app bound domains. https://webkit.org/blog/10882/app-bound-domains/
It doesn’t fit my needs, so I won’t research it for now
I find a solution in Android.
PS. ref: https://stackoverflow.com/questions/55894716/how-to-package-a-hosted-web-app-with-ionic-capacitor/55916297#55916297
It can solve this problem. PS. I use
workboxin the service worker.I would very much appreciate an externally hosted server PWA setup to interface properly with Capacitor’s plugins on iOS and Android. I wonder if anyone above has come across any solutions?
@jcesarmobile
Any info about updates on this issue ? Can we sponsor the fix ?
Still nobody found a solution here ?
Using this kind of functionality is primarily not for the app stores in our case, we really want to use this for apps that are rolled out (enterprise) to operators and employees at our clients. This would drastically reduce the building required to deploy updates to them, as all we would need to do is update the PWA.
Please advise if there is anything that I can do to assist or test to get
server.urlworking for Android and iOS through a service worker on Capacitor.I’m facing this “problem” too…
As a temporary “workaround” (in order to solve this), I force a site reload when the ServiceWorker is Ready. I know and I also don’t like the solution, but I needed to implement this 💩 while this “issue/bug/feature” is addressed.
This code is working for me, at the time as I write this… (is working on production).
Forgive me… 😂