Files
maternal-app/maternal-web/next.config.js
andupetcu 688f9bd57a Add PWA support and Recharts dependency
- Install recharts for analytics dashboard visualizations
- Configure Next.js PWA with next-pwa plugin
- Update manifest.json with app details
- Generate service worker and workbox files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 22:36:40 +03:00

176 lines
4.2 KiB
JavaScript

const withPWA = require('next-pwa')({
dest: 'public',
register: true,
skipWaiting: true,
disable: process.env.NODE_ENV === 'development',
runtimeCaching: [
{
urlPattern: /^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,
handler: 'CacheFirst',
options: {
cacheName: 'google-fonts-webfonts',
expiration: {
maxEntries: 4,
maxAgeSeconds: 365 * 24 * 60 * 60, // 365 days
},
},
},
{
urlPattern: /^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,
handler: 'StaleWhileRevalidate',
options: {
cacheName: 'google-fonts-stylesheets',
expiration: {
maxEntries: 4,
maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days
},
},
},
{
urlPattern: /\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,
handler: 'StaleWhileRevalidate',
options: {
cacheName: 'static-font-assets',
expiration: {
maxEntries: 4,
maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days
},
},
},
{
urlPattern: /\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,
handler: 'StaleWhileRevalidate',
options: {
cacheName: 'static-image-assets',
expiration: {
maxEntries: 64,
maxAgeSeconds: 24 * 60 * 60, // 24 hours
},
},
},
{
urlPattern: /\/_next\/image\?url=.+$/i,
handler: 'StaleWhileRevalidate',
options: {
cacheName: 'next-image',
expiration: {
maxEntries: 64,
maxAgeSeconds: 24 * 60 * 60, // 24 hours
},
},
},
{
urlPattern: /\.(?:mp3|wav|ogg)$/i,
handler: 'CacheFirst',
options: {
rangeRequests: true,
cacheName: 'static-audio-assets',
expiration: {
maxEntries: 32,
maxAgeSeconds: 24 * 60 * 60, // 24 hours
},
},
},
{
urlPattern: /\.(?:mp4)$/i,
handler: 'CacheFirst',
options: {
rangeRequests: true,
cacheName: 'static-video-assets',
expiration: {
maxEntries: 32,
maxAgeSeconds: 24 * 60 * 60, // 24 hours
},
},
},
{
urlPattern: /\.(?:js)$/i,
handler: 'StaleWhileRevalidate',
options: {
cacheName: 'static-js-assets',
expiration: {
maxEntries: 32,
maxAgeSeconds: 24 * 60 * 60, // 24 hours
},
},
},
{
urlPattern: /\.(?:css|less)$/i,
handler: 'StaleWhileRevalidate',
options: {
cacheName: 'static-style-assets',
expiration: {
maxEntries: 32,
maxAgeSeconds: 24 * 60 * 60, // 24 hours
},
},
},
{
urlPattern: /\/_next\/data\/.+\/.+\.json$/i,
handler: 'StaleWhileRevalidate',
options: {
cacheName: 'next-data',
expiration: {
maxEntries: 32,
maxAgeSeconds: 24 * 60 * 60, // 24 hours
},
},
},
{
urlPattern: /\/api\/.*$/i,
handler: 'NetworkFirst',
method: 'GET',
options: {
cacheName: 'apis',
expiration: {
maxEntries: 16,
maxAgeSeconds: 24 * 60 * 60, // 24 hours
},
networkTimeoutSeconds: 10, // fall back to cache if API doesn't respond within 10s
},
},
{
urlPattern: /.*/i,
handler: 'NetworkFirst',
options: {
cacheName: 'others',
expiration: {
maxEntries: 32,
maxAgeSeconds: 24 * 60 * 60, // 24 hours
},
networkTimeoutSeconds: 10,
},
},
],
});
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
// Performance optimizations
compiler: {
removeConsole: process.env.NODE_ENV === 'production',
},
// Image optimization
images: {
formats: ['image/avif', 'image/webp'],
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},
// Production optimizations
swcMinify: true,
// Compression
compress: true,
// Enable experimental features for better performance
experimental: {
optimizePackageImports: ['@mui/material', '@mui/icons-material'],
},
}
module.exports = withPWA(nextConfig)