Integrating PWA with Rails Hotwire and Turbo Streams
Why Combine Hotwire and PWAs?
Hotwire, introduced by Rails 7+, provides Turbo and Stimulus for building interactive, real-time applications without excessive JavaScript.
Combining Hotwire with PWA features enhances performance while keeping development efficient.
1. How Turbo Streams Enhance PWAs
PWAs rely on fast, seamless interactions, and Turbo Streams provide:
- ✅ Server-side rendering with WebSockets → Faster updates without full page reloads.
- ✅ Reduced JavaScript complexity → Eliminates unnecessary React or Vue dependencies.
- ✅ Offline-friendly updates → Works with service workers for caching.
2. Setting Up Turbo Streams in Rails 8
First, add Turbo Streams to a model (e.g., Message
in a chat app):
class Message < ApplicationRecord
after_create_commit -> { broadcast_append_to "chat", target: "messages" }
end
In the view:
<div id="messages">
<%= render @messages %>
</div>
Now, every time a new message is added, Turbo Streams automatically updates the UI in real-time without a page reload.
3. Handling Turbo Streams Offline with Service Workers
To make Turbo Streams work offline, integrate them with service workers:
self.addEventListener('fetch', event => {
if (event.request.url.includes('/turbo-stream')) {
event.respondWith(fetch(event.request).catch(() => {
return new Response('<turbo-stream action="append"></turbo-stream>', { headers: { 'Content-Type': 'text/html' } });
}));
}
});
This ensures that when offline, the app gracefully degrades instead of breaking.