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
- 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
184 lines
5.0 KiB
TypeScript
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'
|
|
}
|
|
}
|
|
})
|