@djangocfg/nextjs 2.1.30 → 2.1.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,6 +17,7 @@
17
17
 
18
18
  ## Features
19
19
 
20
+ - **Zero-Config PWA** - Progressive Web App out of the box (service worker, offline support, manifest)
20
21
  - **Base Next.js Config** - Universal, reusable Next.js configuration factory for monorepos
21
22
  - **AI Documentation** - Search DjangoCFG docs via MCP server and CLI
22
23
  - **Sitemap Generation** - Dynamic XML sitemap generation for SEO
@@ -106,6 +107,71 @@ export default withBundleAnalyzer(createBaseNextConfig({
106
107
  }));
107
108
  ```
108
109
 
110
+ ### PWA (Progressive Web App)
111
+
112
+ **Zero-config PWA** - Works out of the box! Service worker and offline support included automatically.
113
+
114
+ #### 1. Create manifest
115
+
116
+ ```tsx
117
+ // app/manifest.ts
118
+ import { createManifest } from '@djangocfg/nextjs/config';
119
+ import { settings } from '@core/settings';
120
+
121
+ export default createManifest({
122
+ name: settings.app.name,
123
+ description: settings.app.description,
124
+ themeColor: '#ffffff',
125
+ backgroundColor: '#000000',
126
+ icons: {
127
+ logo192: settings.app.icons.logo192,
128
+ logo384: settings.app.icons.logo384,
129
+ logo512: settings.app.icons.logo512,
130
+ },
131
+ });
132
+ ```
133
+
134
+ #### 2. Add manifest metadata
135
+
136
+ ```tsx
137
+ // app/layout.tsx
138
+ import { createManifestMetadata } from '@djangocfg/nextjs/config';
139
+
140
+ export const metadata = {
141
+ ...createManifestMetadata({
142
+ name: 'My App',
143
+ themeColor: '#000000',
144
+ }),
145
+ };
146
+ ```
147
+
148
+ **That's it!** PWA is now enabled in production. Generated files:
149
+ - `/manifest.webmanifest` - From `app/manifest.ts`
150
+ - `/sw.js` - Service worker (auto-generated in production)
151
+ - `/workbox-*.js` - Workbox runtime
152
+
153
+ **Customization** (optional):
154
+
155
+ ```tsx
156
+ // next.config.ts
157
+ export default createBaseNextConfig({
158
+ pwa: {
159
+ dest: 'public',
160
+ disable: process.env.NODE_ENV === 'development', // Disable in dev
161
+ fallbacks: {
162
+ document: '/_offline', // Offline page
163
+ },
164
+ runtimeCaching: [
165
+ // Custom caching rules
166
+ ...defaultRuntimeCaching,
167
+ createApiCacheRule('https://api.example.com'),
168
+ ],
169
+ },
170
+ });
171
+ ```
172
+
173
+ See [PWA.md](./PWA.md) for complete guide.
174
+
109
175
  ### Sitemap Generation
110
176
 
111
177
  Generate dynamic XML sitemaps for SEO:
@@ -1,7 +1,313 @@
1
- import { NextConfig } from 'next';
1
+ import { NextConfig, Metadata, MetadataRoute } from 'next';
2
2
  import { Configuration, Compiler } from 'webpack';
3
3
  export { A as AI_DOCS_HINT, b as MCP_API_URL, M as MCP_BASE_URL, a as MCP_SERVER_URL } from '../constants-HezbftFb.mjs';
4
4
 
5
+ /**
6
+ * PWA (Progressive Web App) Plugin
7
+ *
8
+ * Configures @ducanh2912/next-pwa for service worker and offline support
9
+ * Modern fork that supports Next.js 13+ with app directory
10
+ *
11
+ * @see https://www.npmjs.com/package/@ducanh2912/next-pwa
12
+ */
13
+
14
+ /**
15
+ * Runtime caching handler strategies
16
+ */
17
+ type CacheStrategy = 'CacheFirst' | 'CacheOnly' | 'NetworkFirst' | 'NetworkOnly' | 'StaleWhileRevalidate';
18
+ /**
19
+ * Runtime cache entry configuration
20
+ */
21
+ interface RuntimeCacheEntry {
22
+ urlPattern: RegExp | string | ((context: {
23
+ url: URL;
24
+ request: Request;
25
+ }) => boolean);
26
+ handler: CacheStrategy;
27
+ options?: {
28
+ cacheName?: string;
29
+ expiration?: {
30
+ maxEntries?: number;
31
+ maxAgeSeconds?: number;
32
+ purgeOnQuotaError?: boolean;
33
+ };
34
+ cacheableResponse?: {
35
+ statuses?: number[];
36
+ headers?: Record<string, string>;
37
+ };
38
+ rangeRequests?: boolean;
39
+ backgroundSync?: {
40
+ name: string;
41
+ options?: {
42
+ maxRetentionTime?: number;
43
+ };
44
+ };
45
+ broadcastUpdate?: {
46
+ channelName?: string;
47
+ options?: {
48
+ headersToCheck?: string[];
49
+ };
50
+ };
51
+ matchOptions?: {
52
+ ignoreSearch?: boolean;
53
+ ignoreMethod?: boolean;
54
+ ignoreVary?: boolean;
55
+ };
56
+ networkTimeoutSeconds?: number;
57
+ plugins?: any[];
58
+ fetchOptions?: RequestInit;
59
+ };
60
+ }
61
+ interface PWAPluginOptions {
62
+ /**
63
+ * Destination directory for service worker files
64
+ * @default 'public'
65
+ */
66
+ dest: string;
67
+ /**
68
+ * Disable PWA completely
69
+ * @default false in production, true in development
70
+ * @example disable: process.env.NODE_ENV === 'development'
71
+ */
72
+ disable?: boolean;
73
+ /**
74
+ * Auto-register service worker
75
+ * @default true
76
+ * @description Set to false if you want to register SW manually
77
+ */
78
+ register?: boolean;
79
+ /**
80
+ * URL scope for PWA
81
+ * @default '/'
82
+ * @example '/app' - only /app/** will be PWA
83
+ */
84
+ scope?: string;
85
+ /**
86
+ * Service worker file name
87
+ * @default 'sw.js'
88
+ */
89
+ sw?: string;
90
+ /**
91
+ * Skip waiting for service worker activation
92
+ * @default true
93
+ * @description Activate new SW immediately
94
+ */
95
+ skipWaiting?: boolean;
96
+ /**
97
+ * Client claim - take control of uncontrolled clients immediately
98
+ * @default true
99
+ */
100
+ clientsClaim?: boolean;
101
+ /**
102
+ * Cleanup outdated caches automatically
103
+ * @default true
104
+ */
105
+ cleanupOutdatedCaches?: boolean;
106
+ /**
107
+ * Runtime caching strategies
108
+ * @default defaultRuntimeCaching
109
+ * @see defaultRuntimeCaching for default configuration
110
+ */
111
+ runtimeCaching?: RuntimeCacheEntry[];
112
+ /**
113
+ * Exclude files from build directory precaching
114
+ * @example [/chunks\/images\/.*$/] - don't precache images
115
+ */
116
+ buildExcludes?: (string | RegExp | ((chunk: any) => boolean))[];
117
+ /**
118
+ * Exclude files from public directory precaching
119
+ * @default ['!noprecache/**\/*']
120
+ * @example ['!videos/**\/*', '!large-images/**\/*']
121
+ */
122
+ publicExcludes?: string[];
123
+ /**
124
+ * Cache start URL (_app or / route)
125
+ * @default true
126
+ */
127
+ cacheStartUrl?: boolean;
128
+ /**
129
+ * Dynamic start URL (returns different HTML for different states)
130
+ * @default true
131
+ * @description Set to false if start URL always returns same HTML
132
+ */
133
+ dynamicStartUrl?: boolean;
134
+ /**
135
+ * Redirect URL if start URL redirects (e.g., to /login)
136
+ * @example '/login'
137
+ */
138
+ dynamicStartUrlRedirect?: string;
139
+ /**
140
+ * Enable additional route caching on front-end navigation
141
+ * @default false
142
+ * @description Cache routes when navigating with next/link
143
+ */
144
+ cacheOnFrontEndNav?: boolean;
145
+ /**
146
+ * Subdomain prefix for static files
147
+ * @deprecated Use basePath in next.config.js instead
148
+ */
149
+ subdomainPrefix?: string;
150
+ /**
151
+ * Reload app when device goes back online
152
+ * @default true
153
+ */
154
+ reloadOnOnline?: boolean;
155
+ /**
156
+ * Custom worker directory
157
+ * @default 'worker'
158
+ * @description Directory containing custom worker implementation
159
+ */
160
+ customWorkerDir?: string;
161
+ /**
162
+ * Custom service worker source (for InjectManifest mode)
163
+ * @description Path to your custom service worker source
164
+ */
165
+ swSrc?: string;
166
+ /**
167
+ * Offline fallback pages
168
+ * @example { document: '/_offline', image: '/offline.jpg' }
169
+ */
170
+ fallbacks?: {
171
+ document?: string;
172
+ image?: string;
173
+ audio?: string;
174
+ video?: string;
175
+ font?: string;
176
+ };
177
+ /**
178
+ * Additional workbox options
179
+ * @see https://developer.chrome.com/docs/workbox/modules/workbox-webpack-plugin
180
+ */
181
+ workboxOptions?: Record<string, any>;
182
+ }
183
+ /**
184
+ * Check if @ducanh2912/next-pwa is installed
185
+ *
186
+ * Note: @ducanh2912/next-pwa is included as a dependency,
187
+ * so this should always return true unless there's an installation issue
188
+ */
189
+ declare function isPWAAvailable(): boolean;
190
+ /**
191
+ * Add PWA configuration to Next.js config
192
+ *
193
+ * @example
194
+ * ```ts
195
+ * // Basic usage
196
+ * export default withPWA(nextConfig, {
197
+ * dest: 'public',
198
+ * disable: process.env.NODE_ENV === 'development',
199
+ * });
200
+ *
201
+ * // With custom runtime caching
202
+ * export default withPWA(nextConfig, {
203
+ * dest: 'public',
204
+ * runtimeCaching: [
205
+ * {
206
+ * urlPattern: /^https:\/\/api\.example\.com\/.* /i,
207
+ * handler: 'NetworkFirst',
208
+ * options: {
209
+ * cacheName: 'api-cache',
210
+ * expiration: { maxEntries: 50, maxAgeSeconds: 300 },
211
+ * },
212
+ * },
213
+ * ],
214
+ * });
215
+ *
216
+ * // With offline fallbacks
217
+ * export default withPWA(nextConfig, {
218
+ * dest: 'public',
219
+ * fallbacks: {
220
+ * document: '/_offline',
221
+ * image: '/offline.jpg',
222
+ * },
223
+ * });
224
+ * ```
225
+ */
226
+ declare function withPWA(nextConfig: NextConfig, options?: Partial<PWAPluginOptions>): NextConfig;
227
+ /**
228
+ * Default runtime caching strategies
229
+ *
230
+ * Optimized caching rules for common assets:
231
+ * - Google Fonts (webfonts + stylesheets)
232
+ * - Static assets (images, fonts, audio, video)
233
+ * - Next.js resources (JS, CSS, data, images)
234
+ * - API routes excluded from page cache
235
+ *
236
+ * @example
237
+ * ```ts
238
+ * // Use default caching
239
+ * withPWA(nextConfig, {
240
+ * dest: 'public',
241
+ * runtimeCaching: defaultRuntimeCaching,
242
+ * });
243
+ *
244
+ * // Extend with custom rules
245
+ * withPWA(nextConfig, {
246
+ * dest: 'public',
247
+ * runtimeCaching: [
248
+ * ...defaultRuntimeCaching,
249
+ * {
250
+ * urlPattern: /^https:\/\/api\.example\.com\/.* /i,
251
+ * handler: 'NetworkFirst',
252
+ * options: { cacheName: 'api-cache' },
253
+ * },
254
+ * ],
255
+ * });
256
+ * ```
257
+ */
258
+ declare const defaultRuntimeCaching: RuntimeCacheEntry[];
259
+ /**
260
+ * Helper: Create API caching rule
261
+ *
262
+ * @example
263
+ * ```ts
264
+ * createApiCacheRule('https://api.example.com', {
265
+ * strategy: 'NetworkFirst',
266
+ * maxAge: 300, // 5 minutes
267
+ * });
268
+ * ```
269
+ */
270
+ declare function createApiCacheRule(apiUrl: string, options?: {
271
+ strategy?: CacheStrategy;
272
+ maxAge?: number;
273
+ maxEntries?: number;
274
+ cacheName?: string;
275
+ }): RuntimeCacheEntry;
276
+ /**
277
+ * Helper: Create static asset caching rule
278
+ *
279
+ * @example
280
+ * ```ts
281
+ * createStaticAssetRule(['jpg', 'png', 'webp'], {
282
+ * strategy: 'CacheFirst',
283
+ * maxAge: 86400, // 1 day
284
+ * });
285
+ * ```
286
+ */
287
+ declare function createStaticAssetRule(extensions: string[], options?: {
288
+ strategy?: CacheStrategy;
289
+ maxAge?: number;
290
+ maxEntries?: number;
291
+ cacheName?: string;
292
+ }): RuntimeCacheEntry;
293
+ /**
294
+ * Helper: Create CDN caching rule
295
+ *
296
+ * @example
297
+ * ```ts
298
+ * createCdnCacheRule('https://cdn.example.com', {
299
+ * strategy: 'CacheFirst',
300
+ * maxAge: 2592000, // 30 days
301
+ * });
302
+ * ```
303
+ */
304
+ declare function createCdnCacheRule(cdnUrl: string, options?: {
305
+ strategy?: CacheStrategy;
306
+ maxAge?: number;
307
+ maxEntries?: number;
308
+ cacheName?: string;
309
+ }): RuntimeCacheEntry;
310
+
5
311
  /**
6
312
  * Base Next.js Configuration Factory
7
313
  *
@@ -49,6 +355,12 @@ interface BaseNextConfigOptions {
49
355
  * Set to ['*'] to allow all origins, or specify domains like ['https://djangocfg.com']
50
356
  */
51
357
  allowIframeFrom?: string[];
358
+ /**
359
+ * PWA configuration options
360
+ * Set to false to disable PWA, or provide custom options
361
+ * @default { enabled: true (in production), disable: true (in development) }
362
+ */
363
+ pwa?: PWAPluginOptions | false;
52
364
  /** Custom webpack configuration function (called after base webpack logic) */
53
365
  webpack?: (config: Configuration, options: {
54
366
  isServer: boolean;
@@ -357,4 +669,95 @@ declare function addCompressionPlugins(config: Configuration, options?: Compress
357
669
  */
358
670
  declare function isCompressionAvailable(): boolean;
359
671
 
360
- export { type BaseNextConfigOptions, type CompressionPluginOptions, DEFAULT_OPTIMIZE_PACKAGES, DEFAULT_TRANSPILE_PACKAGES, DJANGOCFG_PACKAGES, DJANGO_CFG_BANNER, DevStartupPlugin, type DevStartupPluginOptions, type InstallOptions, type InstallProgress, type MissingPackage, OPTIONAL_PACKAGES, PACKAGE_NAME, PEER_DEPENDENCIES, type PackageDefinition, type PackageVersion, type UpdateOptions, addCompressionPlugins, buildInstallCommand, buildSingleInstallCommand, checkAndInstallPackages, checkAndUpdatePackages, checkForUpdate, checkForUpdates, checkPackages, createBaseNextConfig, deepMerge, detectPackageManager, fetchLatestVersion, getApiUrl, getBasePath, getCurrentVersion, getInstalledVersion, getMissingPackages, getOutdatedPackages, getPackagesForContext, getSiteUrl, getUpdateCommand, installPackages, installPackagesWithProgress, isCI, isCompressionAvailable, isDev, isPackageInstalled, isProduction, isStaticBuild, printVersionInfo, resetDevStartupState, resetInstallerPreferences, resetUpdaterPreferences, updatePackagesWithProgress };
672
+ /**
673
+ * PWA Manifest Metadata Utilities
674
+ *
675
+ * Helper functions for creating Next.js metadata for PWA manifest
676
+ */
677
+
678
+ interface ManifestConfig {
679
+ name: string;
680
+ shortName?: string;
681
+ description?: string;
682
+ themeColor?: string;
683
+ backgroundColor?: string;
684
+ display?: 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser';
685
+ orientation?: 'portrait' | 'landscape' | 'any';
686
+ startUrl?: string;
687
+ scope?: string;
688
+ lang?: string;
689
+ dir?: 'ltr' | 'rtl' | 'auto';
690
+ icons?: {
691
+ src: string;
692
+ sizes: string;
693
+ type?: string;
694
+ purpose?: string;
695
+ }[];
696
+ }
697
+ /**
698
+ * Icon paths configuration
699
+ */
700
+ interface IconPaths {
701
+ logo192?: string;
702
+ logo384?: string;
703
+ logo512?: string;
704
+ }
705
+ /**
706
+ * Create manifest metadata for Next.js app
707
+ *
708
+ * @example
709
+ * ```typescript
710
+ * export const metadata: Metadata = {
711
+ * ...createManifestMetadata({
712
+ * name: 'My App',
713
+ * shortName: 'App',
714
+ * description: 'My awesome app',
715
+ * }),
716
+ * };
717
+ * ```
718
+ */
719
+ declare function createManifestMetadata(config: ManifestConfig): Metadata;
720
+ /**
721
+ * Create Next.js manifest function
722
+ *
723
+ * Use this in your app/manifest.ts file
724
+ *
725
+ * @example
726
+ * ```typescript
727
+ * // app/manifest.ts
728
+ * import { createManifest } from '@djangocfg/nextjs/config';
729
+ * import { settings } from '@core/settings';
730
+ *
731
+ * export default createManifest({
732
+ * name: settings.app.name,
733
+ * description: settings.app.description,
734
+ * icons: {
735
+ * logo192: settings.app.icons.logo192,
736
+ * logo384: settings.app.icons.logo384,
737
+ * logo512: settings.app.icons.logo512,
738
+ * },
739
+ * });
740
+ * ```
741
+ */
742
+ declare function createManifest(config: {
743
+ name: string;
744
+ shortName?: string;
745
+ description?: string;
746
+ themeColor?: string;
747
+ backgroundColor?: string;
748
+ display?: 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser';
749
+ orientation?: 'portrait' | 'landscape' | 'any';
750
+ startUrl?: string;
751
+ scope?: string;
752
+ lang?: string;
753
+ dir?: 'ltr' | 'rtl' | 'auto';
754
+ icons?: IconPaths | ManifestConfig['icons'];
755
+ }): () => MetadataRoute.Manifest;
756
+ /**
757
+ * Generate manifest.json content (legacy)
758
+ *
759
+ * @deprecated Use createManifest() instead
760
+ */
761
+ declare function generateManifest(config: ManifestConfig): Record<string, any>;
762
+
763
+ export { type BaseNextConfigOptions, type CacheStrategy, type CompressionPluginOptions, DEFAULT_OPTIMIZE_PACKAGES, DEFAULT_TRANSPILE_PACKAGES, DJANGOCFG_PACKAGES, DJANGO_CFG_BANNER, DevStartupPlugin, type DevStartupPluginOptions, type IconPaths, type InstallOptions, type InstallProgress, type ManifestConfig, type MissingPackage, OPTIONAL_PACKAGES, PACKAGE_NAME, PEER_DEPENDENCIES, type PWAPluginOptions, type PackageDefinition, type PackageVersion, type RuntimeCacheEntry, type UpdateOptions, addCompressionPlugins, buildInstallCommand, buildSingleInstallCommand, checkAndInstallPackages, checkAndUpdatePackages, checkForUpdate, checkForUpdates, checkPackages, createApiCacheRule, createBaseNextConfig, createCdnCacheRule, createManifest, createManifestMetadata, createStaticAssetRule, deepMerge, defaultRuntimeCaching, detectPackageManager, fetchLatestVersion, generateManifest, getApiUrl, getBasePath, getCurrentVersion, getInstalledVersion, getMissingPackages, getOutdatedPackages, getPackagesForContext, getSiteUrl, getUpdateCommand, installPackages, installPackagesWithProgress, isCI, isCompressionAvailable, isDev, isPWAAvailable, isPackageInstalled, isProduction, isStaticBuild, printVersionInfo, resetDevStartupState, resetInstallerPreferences, resetUpdaterPreferences, updatePackagesWithProgress, withPWA };