Making a Firefox Extension Work Offline — Service Workers vs. Cache API
A common question when building browser extensions: how do you handle offline or spotty network conditions? Here is what I learned building the Weather & Clock Dashboard.
The Problem
The extension fetches weather data from an external API. If the user opens a new tab with no internet connection, they should see the last known weather, not an error.
Option 1: Service Workers
Service workers can intercept network requests and serve cached responses. But in MV3 Firefox extensions, service workers have limitations — they are not persistent and can be terminated.
// manifest.json
"background": { "service_worker": "background.js" }
Option 2: browser.storage.local (What I Used)
For an extension that just needs to cache the last API response, browser.storage.local is simpler and more reliable than a service worker:
async function getWeather(city) {
const CACHE_KEY = 'weather_cache';
const CACHE_TTL = 10 * 60 * 1000; // 10 minutes
// Check cache first
const { weather_cache } = await browser.storage.local.get(CACHE_KEY);
if (weather_cache && Date.now() - weather_cache.timestamp < CACHE_TTL) {
return weather_cache.data;
}
try {
const resp = await fetch(`https://wttr.in/${city}?format=j1`);
const data = await resp.json();
// Store in cache
await browser.storage.local.set({
[CACHE_KEY]: { data, timestamp: Date.now() }
});
return data;
} catch (err) {
// Return stale cache if available
return weather_cache?.data || null;
}
}
Why This Works Better
- Survives offline — returns last good data even without network
- Survives extension reload — data persists across browser sessions
- No service worker complexity — simpler mental model
- Reduces API calls — cached for 10 minutes
Showing Stale Data
When showing cached data, indicate it to the user:
const isStale = Date.now() - cache.timestamp > CACHE_TTL;
if (isStale) {
showWeather(cache.data);
weatherEl.classList.add('stale'); // gray out or add "last updated" label
}
This pattern — cache-first with stale fallback — is robust for any extension that fetches external data.
Top comments (0)