Files
pantry/app/nuxt.config.ts
Pantry Lead Agent b98b3bf222
Some checks failed
Pull Request Checks / Validate PR (pull_request) Has been cancelled
Deploy to Coolify / Code Quality (pull_request) Has been cancelled
Deploy to Coolify / Run Tests (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Development (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Production (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Test (pull_request) Has been cancelled
feat: configure service worker and offline support (#34)
- Enhance Workbox configuration with comprehensive caching strategies
- Add separate caching for Supabase REST API, Storage, and Auth
- Configure Open Food Facts API caching (30-day cache)
- Add offline fallback page with retry functionality
- Create useOnlineStatus composable for network monitoring
- Add OfflineBanner component for user feedback
- Configure skipWaiting and clientsClaim for instant updates
- Cache Google Fonts and product images

Caching strategies:
- Network-first: Supabase REST API (fresh data priority)
- Network-only: Auth endpoints (never cache sensitive auth)
- Cache-first: Images, fonts, product data (performance)
- Offline fallback: /offline page for failed navigations

Closes #34
2026-02-25 00:07:44 +00:00

184 lines
5.0 KiB
TypeScript

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
compatibilityDate: '2025-07-15',
devtools: { enabled: true },
modules: [
'@nuxt/ui',
'@nuxt/fonts',
'@vite-pwa/nuxt'
],
runtimeConfig: {
public: {
supabaseUrl: process.env.NUXT_PUBLIC_SUPABASE_URL || 'http://localhost:54321',
supabaseAnonKey: process.env.NUXT_PUBLIC_SUPABASE_ANON_KEY || ''
}
},
colorMode: {
preference: 'light'
},
pwa: {
registerType: 'autoUpdate',
manifest: {
name: 'Pantry - Smart Inventory Manager',
short_name: 'Pantry',
description: 'Track your household pantry inventory with ease. Barcode scanning, smart organization, and multi-user support.',
theme_color: '#10b981',
background_color: '#ffffff',
display: 'standalone',
orientation: 'portrait',
scope: '/',
start_url: '/',
categories: ['productivity', 'lifestyle'],
icons: [
{
src: '/icon-192x192.png',
sizes: '192x192',
type: 'image/png',
purpose: 'any'
},
{
src: '/icon-512x512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any'
},
{
src: '/icon-192x192-maskable.png',
sizes: '192x192',
type: 'image/png',
purpose: 'maskable'
},
{
src: '/icon-512x512-maskable.png',
sizes: '512x512',
type: 'image/png',
purpose: 'maskable'
}
],
screenshots: [
{
src: '/screenshot-mobile.png',
sizes: '390x844',
type: 'image/png',
form_factor: 'narrow',
label: 'Pantry inventory view on mobile'
},
{
src: '/screenshot-desktop.png',
sizes: '1920x1080',
type: 'image/png',
form_factor: 'wide',
label: 'Pantry inventory view on desktop'
}
]
},
workbox: {
navigateFallback: '/offline',
navigateFallbackDenylist: [/^\/api\//],
globPatterns: ['**/*.{js,css,html,png,svg,ico,woff,woff2}'],
cleanupOutdatedCaches: true,
skipWaiting: true,
clientsClaim: true,
runtimeCaching: [
// Supabase API - Network first with fallback
{
urlPattern: /^https:\/\/.*\.supabase\.co\/rest\/.*/i,
handler: 'NetworkFirst',
options: {
cacheName: 'supabase-rest-api',
networkTimeoutSeconds: 10,
expiration: {
maxEntries: 50,
maxAgeSeconds: 60 * 60 // 1 hour
},
cacheableResponse: {
statuses: [0, 200]
}
}
},
// Supabase Auth - Network only (don't cache auth)
{
urlPattern: /^https:\/\/.*\.supabase\.co\/auth\/.*/i,
handler: 'NetworkOnly'
},
// Supabase Storage - Cache first for images
{
urlPattern: /^https:\/\/.*\.supabase\.co\/storage\/.*/i,
handler: 'CacheFirst',
options: {
cacheName: 'supabase-storage',
expiration: {
maxEntries: 100,
maxAgeSeconds: 60 * 60 * 24 * 7 // 1 week
},
cacheableResponse: {
statuses: [0, 200]
}
}
},
// Open Food Facts API - Cache first with network fallback
{
urlPattern: /^https:\/\/world\.openfoodfacts\.org\/.*/i,
handler: 'CacheFirst',
options: {
cacheName: 'openfoodfacts-api',
expiration: {
maxEntries: 200,
maxAgeSeconds: 60 * 60 * 24 * 30 // 30 days
},
cacheableResponse: {
statuses: [0, 200]
}
}
},
// External images - Cache first
{
urlPattern: /^https:\/\/images\.openfoodfacts\.org\/.*/i,
handler: 'CacheFirst',
options: {
cacheName: 'product-images',
expiration: {
maxEntries: 100,
maxAgeSeconds: 60 * 60 * 24 * 30 // 30 days
},
cacheableResponse: {
statuses: [0, 200]
}
}
},
// Google Fonts - Cache first
{
urlPattern: /^https:\/\/fonts\.googleapis\.com\/.*/i,
handler: 'CacheFirst',
options: {
cacheName: 'google-fonts-stylesheets',
expiration: {
maxEntries: 20,
maxAgeSeconds: 60 * 60 * 24 * 365 // 1 year
}
}
},
{
urlPattern: /^https:\/\/fonts\.gstatic\.com\/.*/i,
handler: 'CacheFirst',
options: {
cacheName: 'google-fonts-webfonts',
expiration: {
maxEntries: 30,
maxAgeSeconds: 60 * 60 * 24 * 365 // 1 year
}
}
}
]
},
devOptions: {
enabled: true,
type: 'module'
}
}
})