Can We Use StimulusJS for PWA Development in Rails?

Yes, StimulusJS can be used alongside a Rails PWA, but it does not replace Service Workers.

StimulusJS enhances frontend interactions, while Service Workers handle caching, offline support, and push notifications at the browser level.

How StimulusJS Can Help in PWA Development?

Here’s how Stimulus can complement your PWA:

Example: Using Stimulus to Register a Service Worker

Instead of writing raw JavaScript in application.html.erb, you can create a Stimulus controller for managing the Service Worker.

1. Create a Stimulus Controller

rails generate stimulus pwa

2. Implement Service Worker Registration in Stimulus

Edit pwa_controller.js:

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  connect() {
    if ("serviceWorker" in navigator) {
      navigator.serviceWorker.register("/service_worker.js")
        .then(registration => console.log("Service Worker Registered", registration))
        .catch(error => console.error("Service Worker Registration Failed", error));
    }
  }
}

3. Add Stimulus Controller to application.html.erb

<body data-controller="pwa">
  <h1>My Rails PWA</h1>
</body>

Now, the Service Worker will register automatically when the page loads.

Example: Using Stimulus for Network Status Updates

You can also use Stimulus to notify users when they go offline or come back online.

1. Update pwa_controller.js

export default class extends Controller {
  connect() {
    window.addEventListener("offline", () => this.updateStatus("You are offline"));
    window.addEventListener("online", () => this.updateStatus("You are online"));
  }

  updateStatus(message) {
    alert(message); // You can replace this with a better UI update
  }
}

Do We Still Need service_worker.js?

Yes! Rails cannot replace Service Workers because they are part of the browser API. However, Stimulus can help in making Service Worker management easier.

For a full Rails PWA, you’ll need both Stimulus and Service Workers working together.