Discussion about caching issues and image optimization in Gatsby and Netlify site, with a mention of search functionality.
This is a classic Gatsby + service worker caching issue! When your client updates content in Sanity, they're seeing stale content because of how static site generators and service workers work. Let me break down what's happening and how to fix it.
The Problem
You're dealing with two layers of caching:
- Static generation: Gatsby builds static pages at build time, so updates in Sanity don't appear until you rebuild the site
- Service worker caching: If you're using
gatsby-plugin-offline, it aggressively caches pages for offline functionality, which means visitors see the cached version until they manually refresh
The content appearing after a hard refresh is the telltale sign of service worker caching issues.
The Solution: Auto-Rebuild + Handle Service Workers
You need to fix this from both angles:
1. Trigger Netlify Rebuilds When Content Changes
The most reliable approach is setting up a webhook from Sanity to trigger Netlify rebuilds automatically when content changes.
Step 1: Create a Netlify Build Hook
In your Netlify dashboard:
- Go to Site settings → Build & deploy → Build hooks
- Click Add build hook
- Give it a name like "Sanity Content Update"
- Copy the webhook URL
Step 2: Set Up a Sanity Webhook
In your Sanity project dashboard (manage.sanity.io):
- Go to API → Webhooks
- Click Create webhook
- Name it (e.g., "Trigger Netlify Build")
- Paste your Netlify build hook URL
- Set the dataset (usually
production) - For Filter, you can use
*to trigger on all document changes, or be more specific like_type == "post" || _type == "page" - Enable On create, On update, and On delete
- Save the webhook
Now whenever your client publishes content changes in Sanity, Netlify will automatically rebuild the site.
2. Fix the Service Worker Stale Content Issue
If you're using gatsby-plugin-offline, add this to your gatsby-browser.js file:
export const onServiceWorkerUpdateReady = () => {
window.location.reload()
}This automatically reloads the page when a new service worker (with fresh content from your rebuild) is ready, ensuring visitors see the updated content without needing to manually refresh.
Alternative: Show a notification instead of auto-reloading:
export const onServiceWorkerUpdateReady = () => {
const answer = window.confirm(
`This site has been updated. Reload to display the latest version?`
)
if (answer === true) {
window.location.reload()
}
}3. Consider Removing gatsby-plugin-offline
Many developers find that gatsby-plugin-offline causes more headaches than it's worth. If offline functionality isn't critical for your use case, consider removing it entirely from your gatsby-config.js. Modern browsers provide reasonable caching without it, and you'll avoid these stale content issues altogether.
To remove it, simply delete it from your plugins array and run npm uninstall gatsby-plugin-offline.
Additional Considerations
Avoid Build Spam: If your client makes lots of rapid edits, each one will trigger a new build. Consider:
- Educating them to batch changes before publishing
- Using Netlify's build rate limiting features if needed
Check Cache Headers: Look at your netlify.toml file and make sure you're not setting overly aggressive Cache-Control headers that could compound the caching issues.
Build Times: Gatsby rebuilds can take several minutes depending on your site size. Set expectations with your client that there will be a short delay (typically 2-5 minutes) between publishing and seeing changes live.
Alternative Approach: If you need more real-time updates without waiting for rebuilds, you might want to explore Sanity's Live Content API with frameworks that support it, though this would require moving away from Gatsby's static generation approach.
The combination of webhook-triggered rebuilds + proper service worker update handling with onServiceWorkerUpdateReady should completely solve your stale content problem!
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.