Appearance
Nitro Cache Invalidation
Overview
The frontend uses Nitro's built-in caching to serve frequently-accessed data faster and reduce backend load. When data changes in the backend, the cache needs to be invalidated.
Cached Endpoints
| Endpoint | Cache Duration | Stale Duration | Description |
|---|---|---|---|
/api/settings | 24 hours | 7 days | Site settings (rarely change) |
/api/competitions | 60 seconds | 5 minutes | Public competitions list |
/api/competitions/featured | 2 minutes | 10 minutes | Featured competitions |
Cache Invalidation
Site Settings
When site settings are updated in the admin panel, the backend should invalidate the frontend cache:
typescript
// In your backend settings controller (after updating settings)
const FRONTEND_URL = process.env.FRONTEND_URL || 'http://localhost:4000'
const CACHE_SECRET = process.env.CACHE_INVALIDATION_SECRET
try {
await fetch(`${FRONTEND_URL}/api/cache/invalidate/settings`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${CACHE_SECRET}`
}
})
console.log('Frontend settings cache invalidated successfully')
} catch (error) {
console.error('Failed to invalidate frontend cache:', error)
// Non-critical - cache will expire after 24 hours anyway
}Environment Variables
Backend .env:
bash
FRONTEND_URL=http://localhost:4000 # or https://yourdomain.com in production
CACHE_INVALIDATION_SECRET=your-secret-token-hereFrontend .env:
bash
CACHE_INVALIDATION_SECRET=your-secret-token-here # Same secret as backendGenerate a secure secret:
bash
# Generate random secret
openssl rand -hex 32Security
- The cache invalidation endpoint requires authentication via Bearer token
- The secret should be strong (32+ characters) and kept confidential
- Only the backend should have access to this endpoint
- Invalid requests return 401 Unauthorized
Error Handling
Cache invalidation is non-critical:
- If invalidation fails, the cache will automatically expire after the TTL (24 hours for settings)
- The backend should log failures but not block the user's request
- Use try-catch to handle network errors gracefully
Example Implementation in Backend
File: src/controllers/siteSettingsController.ts
typescript
import { Response } from 'express'
import { AuthRequest } from '../types/auth'
const invalidateFrontendCache = async () => {
const FRONTEND_URL = process.env.FRONTEND_URL
const CACHE_SECRET = process.env.CACHE_INVALIDATION_SECRET
if (!FRONTEND_URL || !CACHE_SECRET) {
console.warn('Cache invalidation not configured (missing FRONTEND_URL or CACHE_INVALIDATION_SECRET)')
return
}
try {
const response = await fetch(`${FRONTEND_URL}/api/cache/invalidate/settings`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${CACHE_SECRET}`
}
})
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
}
console.info('Frontend settings cache invalidated successfully')
} catch (error) {
console.error('Failed to invalidate frontend cache:', error)
// Non-critical - don't throw, just log
}
}
export const updateSiteSettings = async (req: AuthRequest, res: Response) => {
try {
// ... update settings logic ...
// Invalidate frontend cache (fire and forget - don't await)
invalidateFrontendCache().catch(err => {
console.error('Cache invalidation error:', err)
})
res.json({ success: true, data: updatedSettings })
} catch (error) {
// ... error handling ...
}
}Testing Cache Invalidation
1. Test the cached endpoint:
bash
# First request - hits backend, caches for 24 hours
curl http://localhost:4000/api/settings
# Second request - served from cache (instant)
curl http://localhost:4000/api/settings2. Test cache invalidation:
bash
# Invalidate the cache
curl -X POST http://localhost:4000/api/cache/invalidate/settings \
-H "Authorization: Bearer your-secret-token-here"
# Response:
# {"success":true,"message":"Site settings cache invalidated","timestamp":"2025-12-16T13:00:00.000Z"}3. Verify cache was cleared:
bash
# This should fetch fresh data from backend again
curl http://localhost:4000/api/settingsMonitoring
Cache performance metrics are automatically logged:
- Cache hits/misses
- Response times
- Invalidation requests
Check Nitro logs for cache-related messages:
[Cache Invalidation] Site settings cache cleared successfully
[API Proxy] Failed to fetch site settings: <error>Best Practices
- Always invalidate after updates: Call the invalidation endpoint after any settings change
- Don't block on invalidation: Use fire-and-forget pattern (don't await)
- Log failures: Cache invalidation failures are non-critical but should be logged
- Use environment variables: Never hardcode the secret or URLs
- Test in staging: Verify cache invalidation works before deploying to production
Troubleshooting
Cache not invalidating?
- Check that
CACHE_INVALIDATION_SECRETmatches in both backend and frontend - Verify
FRONTEND_URLpoints to the correct frontend server - Check network connectivity between backend and frontend
- Look for errors in backend logs when calling the invalidation endpoint
401 Unauthorized errors?
- Verify the secret token is correct
- Check the Authorization header format:
Bearer <token> - Ensure the secret is not empty or undefined
Cache still serving stale data?
- Check if you're testing the right endpoint (
/api/settingsnot${API_BASE}/settings) - Verify the invalidation request succeeded (check response)
- Clear browser cache if testing in a browser
- Wait a few seconds for Nitro to finish clearing the cache