@djangocfg/layouts 2.1.37 → 2.1.39
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 +204 -18
- package/package.json +5 -5
- package/src/components/errors/index.ts +9 -0
- package/src/components/errors/types.ts +38 -0
- package/src/layouts/AppLayout/AppLayout.tsx +33 -45
- package/src/layouts/AppLayout/BaseApp.tsx +104 -33
- package/src/layouts/AuthLayout/AuthContext.tsx +7 -1
- package/src/layouts/AuthLayout/OAuthProviders.tsx +1 -10
- package/src/layouts/AuthLayout/OTPForm.tsx +1 -0
- package/src/layouts/PrivateLayout/PrivateLayout.tsx +1 -1
- package/src/layouts/PublicLayout/PublicLayout.tsx +1 -1
- package/src/layouts/PublicLayout/components/PublicMobileDrawer.tsx +1 -1
- package/src/layouts/PublicLayout/components/PublicNavigation.tsx +1 -1
- package/src/layouts/_components/UserMenu.tsx +1 -1
- package/src/layouts/index.ts +1 -1
- package/src/layouts/types/index.ts +47 -0
- package/src/layouts/types/layout.types.ts +61 -0
- package/src/layouts/types/providers.types.ts +65 -0
- package/src/layouts/types/ui.types.ts +103 -0
- package/src/snippets/Analytics/index.ts +1 -0
- package/src/snippets/Analytics/types.ts +10 -0
- package/src/snippets/PWAInstall/@docs/README.md +92 -0
- package/src/snippets/PWAInstall/README.md +185 -0
- package/src/snippets/{PWA → PWAInstall}/components/A2HSHint.tsx +85 -84
- package/src/snippets/PWAInstall/components/DesktopGuide.tsx +229 -0
- package/src/snippets/PWAInstall/context/InstallContext.tsx +102 -0
- package/src/snippets/{PWA → PWAInstall}/hooks/useInstallPrompt.ts +3 -0
- package/src/snippets/{PWA → PWAInstall}/index.ts +12 -31
- package/src/snippets/{PWA → PWAInstall}/types/components.ts +0 -6
- package/src/snippets/PWAInstall/types/config.ts +22 -0
- package/src/snippets/{PWA → PWAInstall}/types/index.ts +4 -4
- package/src/snippets/{PWA → PWAInstall}/utils/localStorage.ts +1 -23
- package/src/snippets/PushNotifications/@docs/README.md +191 -0
- package/src/snippets/PushNotifications/@docs/guides/django-integration.md +648 -0
- package/src/snippets/PushNotifications/@docs/guides/service-worker.md +467 -0
- package/src/snippets/PushNotifications/@docs/guides/vapid-setup.md +352 -0
- package/src/snippets/PushNotifications/README.md +328 -0
- package/src/snippets/{PWA → PushNotifications}/config.ts +2 -2
- package/src/snippets/PushNotifications/context/DjangoPushContext.tsx +190 -0
- package/src/snippets/{PWA → PushNotifications}/hooks/useDjangoPush.ts +63 -81
- package/src/snippets/{PWA → PushNotifications}/hooks/usePushNotifications.ts +12 -8
- package/src/snippets/PushNotifications/index.ts +87 -0
- package/src/snippets/PushNotifications/types/config.ts +28 -0
- package/src/snippets/PushNotifications/types/index.ts +9 -0
- package/src/snippets/PushNotifications/utils/localStorage.ts +60 -0
- package/src/snippets/PushNotifications/utils/logger.ts +149 -0
- package/src/snippets/PushNotifications/utils/platform.ts +151 -0
- package/src/snippets/index.ts +37 -12
- package/src/layouts/shared/index.ts +0 -21
- package/src/layouts/shared/types.ts +0 -247
- package/src/snippets/PWA/@refactoring/ARCHITECTURE_ANALYSIS.md +0 -1179
- package/src/snippets/PWA/@refactoring/EXECUTIVE_SUMMARY.md +0 -271
- package/src/snippets/PWA/@refactoring/README.md +0 -204
- package/src/snippets/PWA/@refactoring/REFACTORING_PROPOSALS.md +0 -1109
- package/src/snippets/PWA/@refactoring2/COMPARISON-WITH-NEXTJS.md +0 -718
- package/src/snippets/PWA/@refactoring2/P1-FIXES-COMPLETED.md +0 -188
- package/src/snippets/PWA/@refactoring2/POST-P0-ANALYSIS.md +0 -362
- package/src/snippets/PWA/@refactoring2/README.md +0 -85
- package/src/snippets/PWA/@refactoring2/RECOMMENDATIONS.md +0 -1321
- package/src/snippets/PWA/@refactoring2/REMAINING-ISSUES.md +0 -557
- package/src/snippets/PWA/README.md +0 -387
- package/src/snippets/PWA/context/DjangoPushContext.tsx +0 -105
- package/src/snippets/PWA/context/InstallContext.tsx +0 -118
- package/src/snippets/PWA/context/PushContext.tsx +0 -156
- /package/src/layouts/{shared → types}/README.md +0 -0
- /package/src/snippets/{PWA/@docs/research.md → PWAInstall/@docs/research/ios-android-install-flows.md} +0 -0
- /package/src/snippets/{PWA → PWAInstall}/components/IOSGuide.tsx +0 -0
- /package/src/snippets/{PWA → PWAInstall}/components/IOSGuideDrawer.tsx +0 -0
- /package/src/snippets/{PWA → PWAInstall}/components/IOSGuideModal.tsx +0 -0
- /package/src/snippets/{PWA → PWAInstall}/hooks/useIsPWA.ts +0 -0
- /package/src/snippets/{PWA → PWAInstall}/types/install.ts +0 -0
- /package/src/snippets/{PWA → PWAInstall}/types/platform.ts +0 -0
- /package/src/snippets/{PWA → PWAInstall}/utils/logger.ts +0 -0
- /package/src/snippets/{PWA → PWAInstall}/utils/platform.ts +0 -0
- /package/src/snippets/{PWA → PushNotifications}/components/PushPrompt.tsx +0 -0
- /package/src/snippets/{PWA → PushNotifications}/types/push.ts +0 -0
- /package/src/snippets/{PWA → PushNotifications}/utils/vapid.ts +0 -0
|
@@ -1,718 +0,0 @@
|
|
|
1
|
-
# Comparison: layouts/PWA vs nextjs/PWA
|
|
2
|
-
|
|
3
|
-
**Date**: December 2025
|
|
4
|
-
**Purpose**: Compare architectures and identify integration opportunities
|
|
5
|
-
|
|
6
|
-
## Executive Summary
|
|
7
|
-
|
|
8
|
-
**layouts/PWA** and **nextjs/PWA** solve different parts of the PWA puzzle:
|
|
9
|
-
|
|
10
|
-
| Package | Focus | Strength |
|
|
11
|
-
|---------|-------|----------|
|
|
12
|
-
| **layouts** | UI/UX for install prompts + push notifications | User-facing components |
|
|
13
|
-
| **nextjs** | Build-time configuration + service worker generation | Developer tooling |
|
|
14
|
-
|
|
15
|
-
**Key Insight**: These packages are **complementary, not competing**
|
|
16
|
-
|
|
17
|
-
**Integration Opportunity**: Use both together for a complete PWA solution
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Architecture Comparison
|
|
22
|
-
|
|
23
|
-
### layouts/PWA Architecture
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
Frontend Runtime (React Components + Hooks)
|
|
27
|
-
├── Installation Flow
|
|
28
|
-
│ ├── A2HSHint (iOS + Android unified prompt)
|
|
29
|
-
│ ├── IOSGuide (visual instructions)
|
|
30
|
-
│ ├── useInstallPrompt (beforeinstallprompt handling)
|
|
31
|
-
│ └── useIsPWA (standalone detection)
|
|
32
|
-
│
|
|
33
|
-
├── Push Notifications
|
|
34
|
-
│ ├── PushPrompt (subscription prompt)
|
|
35
|
-
│ ├── PushContext (state management)
|
|
36
|
-
│ └── usePushNotifications (subscription logic)
|
|
37
|
-
│
|
|
38
|
-
└── Utilities
|
|
39
|
-
├── platform.ts (detection)
|
|
40
|
-
├── logger.ts (conditional logging)
|
|
41
|
-
├── vapid.ts (key validation)
|
|
42
|
-
└── localStorage.ts (persistence)
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
**Focus**: User-facing components for PWA installation and push notifications
|
|
46
|
-
|
|
47
|
-
**Runtime**: Client-side React components
|
|
48
|
-
|
|
49
|
-
### nextjs/PWA Architecture
|
|
50
|
-
|
|
51
|
-
```
|
|
52
|
-
Build-Time Configuration (Next.js Plugin)
|
|
53
|
-
├── Service Worker Generation
|
|
54
|
-
│ ├── withPWA() (Next.js plugin)
|
|
55
|
-
│ ├── Runtime caching strategies
|
|
56
|
-
│ ├── Precaching of static assets
|
|
57
|
-
│ └── Workbox integration
|
|
58
|
-
│
|
|
59
|
-
├── Manifest Generation
|
|
60
|
-
│ ├── manifest.json builder
|
|
61
|
-
│ ├── Icon generation
|
|
62
|
-
│ └── PWA metadata
|
|
63
|
-
│
|
|
64
|
-
└── Utilities
|
|
65
|
-
├── registerServiceWorker()
|
|
66
|
-
├── cacheFirst / networkFirst strategies
|
|
67
|
-
└── Background sync
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
**Focus**: Build-time PWA configuration and service worker management
|
|
71
|
-
|
|
72
|
-
**Runtime**: Build-time code generation + minimal runtime utilities
|
|
73
|
-
|
|
74
|
-
---
|
|
75
|
-
|
|
76
|
-
## Feature Comparison
|
|
77
|
-
|
|
78
|
-
### 1. Installation Flow
|
|
79
|
-
|
|
80
|
-
| Feature | layouts | nextjs | Winner |
|
|
81
|
-
|---------|---------|--------|--------|
|
|
82
|
-
| beforeinstallprompt handling | ✅ Full support | ⚠️ Manual | layouts |
|
|
83
|
-
| iOS Safari instructions | ✅ Visual guide | ❌ None | layouts |
|
|
84
|
-
| Install button component | ✅ A2HSHint | ❌ None | layouts |
|
|
85
|
-
| Standalone detection | ✅ Excellent (cached, reliable) | ⚠️ Basic utility | layouts |
|
|
86
|
-
| Dismissal persistence | ✅ With auto-reset | ❌ None | layouts |
|
|
87
|
-
|
|
88
|
-
**Winner**: **layouts** - Complete UI/UX for installation
|
|
89
|
-
|
|
90
|
-
**nextjs**: Provides manifest generation but no UI
|
|
91
|
-
|
|
92
|
-
### 2. Push Notifications
|
|
93
|
-
|
|
94
|
-
| Feature | layouts | nextjs | Winner |
|
|
95
|
-
|---------|---------|--------|--------|
|
|
96
|
-
| Subscription UI | ✅ PushPrompt | ❌ None | layouts |
|
|
97
|
-
| VAPID validation | ✅ Robust with errors | ⚠️ Basic | layouts |
|
|
98
|
-
| Push state management | ✅ React Context | ❌ None | layouts |
|
|
99
|
-
| Message handling | ✅ Service Worker integration | ⚠️ Manual | layouts |
|
|
100
|
-
| Server-side persistence | ⚠️ Frontend only | ⚠️ Not handled | Tie |
|
|
101
|
-
|
|
102
|
-
**Winner**: **layouts** - Complete push notification flow
|
|
103
|
-
|
|
104
|
-
**nextjs**: Only provides service worker infrastructure
|
|
105
|
-
|
|
106
|
-
### 3. Service Worker
|
|
107
|
-
|
|
108
|
-
| Feature | layouts | nextjs | Winner |
|
|
109
|
-
|---------|---------|--------|--------|
|
|
110
|
-
| Service Worker generation | ❌ Manual | ✅ Automatic (Workbox) | nextjs |
|
|
111
|
-
| Runtime caching | ❌ External | ✅ Built-in | nextjs |
|
|
112
|
-
| Precaching | ❌ Manual | ✅ Automatic | nextjs |
|
|
113
|
-
| Custom strategies | ❌ External | ✅ Configurable | nextjs |
|
|
114
|
-
| Background sync | ❌ Manual | ✅ Built-in | nextjs |
|
|
115
|
-
|
|
116
|
-
**Winner**: **nextjs** - Complete service worker management
|
|
117
|
-
|
|
118
|
-
**layouts**: Assumes service worker exists externally
|
|
119
|
-
|
|
120
|
-
### 4. Manifest
|
|
121
|
-
|
|
122
|
-
| Feature | layouts | nextjs | Winner |
|
|
123
|
-
|---------|---------|--------|--------|
|
|
124
|
-
| manifest.json generation | ❌ Manual | ✅ Automatic | nextjs |
|
|
125
|
-
| Icon generation | ❌ Manual | ✅ Multiple sizes | nextjs |
|
|
126
|
-
| Theme configuration | ❌ Manual | ✅ From config | nextjs |
|
|
127
|
-
| Validation | ❌ None | ✅ Build-time | nextjs |
|
|
128
|
-
|
|
129
|
-
**Winner**: **nextjs** - Automatic manifest generation
|
|
130
|
-
|
|
131
|
-
**layouts**: Expects manifest to exist
|
|
132
|
-
|
|
133
|
-
### 5. Developer Experience
|
|
134
|
-
|
|
135
|
-
| Feature | layouts | nextjs | Winner |
|
|
136
|
-
|---------|---------|--------|--------|
|
|
137
|
-
| Setup complexity | 🟡 Medium | 🟢 Low | nextjs |
|
|
138
|
-
| Documentation | 🟢 Excellent | 🟢 Excellent | Tie |
|
|
139
|
-
| TypeScript support | 🟢 Full | 🟢 Full | Tie |
|
|
140
|
-
| Error messages | 🟢 Excellent | 🟡 Basic | layouts |
|
|
141
|
-
| Debug tools | 🟢 Logger + debug mode | 🟡 Console only | layouts |
|
|
142
|
-
|
|
143
|
-
**Winner**: Depends on use case
|
|
144
|
-
|
|
145
|
-
**nextjs**: Easier to get started (one config)
|
|
146
|
-
|
|
147
|
-
**layouts**: Better runtime debugging
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
## Code Examples
|
|
152
|
-
|
|
153
|
-
### layouts/PWA Usage
|
|
154
|
-
|
|
155
|
-
```tsx
|
|
156
|
-
// app/layout.tsx
|
|
157
|
-
import { PwaProvider } from '@djangocfg/layouts/snippets';
|
|
158
|
-
|
|
159
|
-
export default function RootLayout({ children }) {
|
|
160
|
-
return (
|
|
161
|
-
<html>
|
|
162
|
-
<body>
|
|
163
|
-
<PwaProvider
|
|
164
|
-
enabled
|
|
165
|
-
showInstallHint
|
|
166
|
-
resetAfterDays={3}
|
|
167
|
-
pushNotifications={{
|
|
168
|
-
vapidPublicKey: process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY!,
|
|
169
|
-
subscribeEndpoint: '/api/push/subscribe',
|
|
170
|
-
}}
|
|
171
|
-
>
|
|
172
|
-
{children}
|
|
173
|
-
</PwaProvider>
|
|
174
|
-
</body>
|
|
175
|
-
</html>
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
**What you get**:
|
|
181
|
-
- ✅ Install prompts (iOS + Android)
|
|
182
|
-
- ✅ Push notification prompt
|
|
183
|
-
- ✅ State management
|
|
184
|
-
- ❌ No service worker
|
|
185
|
-
- ❌ No manifest
|
|
186
|
-
- ❌ No caching
|
|
187
|
-
|
|
188
|
-
### nextjs/PWA Usage
|
|
189
|
-
|
|
190
|
-
```js
|
|
191
|
-
// next.config.mjs
|
|
192
|
-
import withPWA from '@djangocfg/nextjs/pwa';
|
|
193
|
-
|
|
194
|
-
export default withPWA({
|
|
195
|
-
dest: 'public',
|
|
196
|
-
register: true,
|
|
197
|
-
skipWaiting: true,
|
|
198
|
-
runtimeCaching: [
|
|
199
|
-
{
|
|
200
|
-
urlPattern: /^https?.*/,
|
|
201
|
-
handler: 'NetworkFirst',
|
|
202
|
-
options: {
|
|
203
|
-
cacheName: 'offlineCache',
|
|
204
|
-
expiration: {
|
|
205
|
-
maxEntries: 200,
|
|
206
|
-
},
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
],
|
|
210
|
-
manifest: {
|
|
211
|
-
name: 'My App',
|
|
212
|
-
short_name: 'App',
|
|
213
|
-
theme_color: '#000000',
|
|
214
|
-
background_color: '#ffffff',
|
|
215
|
-
display: 'standalone',
|
|
216
|
-
icons: [
|
|
217
|
-
{
|
|
218
|
-
src: '/icon-192x192.png',
|
|
219
|
-
sizes: '192x192',
|
|
220
|
-
type: 'image/png',
|
|
221
|
-
},
|
|
222
|
-
],
|
|
223
|
-
},
|
|
224
|
-
});
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
**What you get**:
|
|
228
|
-
- ✅ Service worker (auto-generated)
|
|
229
|
-
- ✅ manifest.json (auto-generated)
|
|
230
|
-
- ✅ Runtime caching
|
|
231
|
-
- ✅ Offline support
|
|
232
|
-
- ❌ No install UI
|
|
233
|
-
- ❌ No push notification UI
|
|
234
|
-
|
|
235
|
-
### Combined Usage (Recommended)
|
|
236
|
-
|
|
237
|
-
```tsx
|
|
238
|
-
// next.config.mjs
|
|
239
|
-
import withPWA from '@djangocfg/nextjs/pwa';
|
|
240
|
-
|
|
241
|
-
export default withPWA({
|
|
242
|
-
// Service worker + manifest configuration
|
|
243
|
-
dest: 'public',
|
|
244
|
-
register: true,
|
|
245
|
-
manifest: { /* ... */ },
|
|
246
|
-
});
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
```tsx
|
|
250
|
-
// app/layout.tsx
|
|
251
|
-
import { PwaProvider } from '@djangocfg/layouts/snippets';
|
|
252
|
-
|
|
253
|
-
export default function RootLayout({ children }) {
|
|
254
|
-
return (
|
|
255
|
-
<html>
|
|
256
|
-
<body>
|
|
257
|
-
{/* UI components for install + push */}
|
|
258
|
-
<PwaProvider
|
|
259
|
-
enabled
|
|
260
|
-
pushNotifications={{ /* ... */ }}
|
|
261
|
-
>
|
|
262
|
-
{children}
|
|
263
|
-
</PwaProvider>
|
|
264
|
-
</body>
|
|
265
|
-
</html>
|
|
266
|
-
);
|
|
267
|
-
}
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
**What you get**:
|
|
271
|
-
- ✅ Service worker (nextjs)
|
|
272
|
-
- ✅ Manifest (nextjs)
|
|
273
|
-
- ✅ Runtime caching (nextjs)
|
|
274
|
-
- ✅ Install UI (layouts)
|
|
275
|
-
- ✅ Push notification UI (layouts)
|
|
276
|
-
- ✅ Complete PWA solution 🎉
|
|
277
|
-
|
|
278
|
-
---
|
|
279
|
-
|
|
280
|
-
## Integration Opportunities
|
|
281
|
-
|
|
282
|
-
### 1. Unified Configuration
|
|
283
|
-
|
|
284
|
-
**Problem**: Two separate configurations
|
|
285
|
-
|
|
286
|
-
**Solution**: Single PWA config object
|
|
287
|
-
|
|
288
|
-
```typescript
|
|
289
|
-
// pwa.config.ts
|
|
290
|
-
export const pwaConfig = {
|
|
291
|
-
// nextjs/PWA configuration
|
|
292
|
-
serviceWorker: {
|
|
293
|
-
dest: 'public',
|
|
294
|
-
register: true,
|
|
295
|
-
skipWaiting: true,
|
|
296
|
-
runtimeCaching: [ /* ... */ ],
|
|
297
|
-
},
|
|
298
|
-
|
|
299
|
-
// Manifest configuration
|
|
300
|
-
manifest: {
|
|
301
|
-
name: 'My App',
|
|
302
|
-
short_name: 'App',
|
|
303
|
-
theme_color: '#000000',
|
|
304
|
-
icons: [ /* ... */ ],
|
|
305
|
-
},
|
|
306
|
-
|
|
307
|
-
// layouts/PWA configuration
|
|
308
|
-
ui: {
|
|
309
|
-
enabled: true,
|
|
310
|
-
showInstallHint: true,
|
|
311
|
-
resetAfterDays: 3,
|
|
312
|
-
pushNotifications: {
|
|
313
|
-
vapidPublicKey: process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY!,
|
|
314
|
-
subscribeEndpoint: '/api/push/subscribe',
|
|
315
|
-
},
|
|
316
|
-
},
|
|
317
|
-
};
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
```tsx
|
|
321
|
-
// next.config.mjs
|
|
322
|
-
import withPWA from '@djangocfg/nextjs/pwa';
|
|
323
|
-
import { pwaConfig } from './pwa.config';
|
|
324
|
-
|
|
325
|
-
export default withPWA(pwaConfig.serviceWorker, pwaConfig.manifest);
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
```tsx
|
|
329
|
-
// app/layout.tsx
|
|
330
|
-
import { PwaProvider } from '@djangocfg/layouts/snippets';
|
|
331
|
-
import { pwaConfig } from '@/pwa.config';
|
|
332
|
-
|
|
333
|
-
export default function RootLayout({ children }) {
|
|
334
|
-
return (
|
|
335
|
-
<html>
|
|
336
|
-
<body>
|
|
337
|
-
<PwaProvider {...pwaConfig.ui}>
|
|
338
|
-
{children}
|
|
339
|
-
</PwaProvider>
|
|
340
|
-
</body>
|
|
341
|
-
</html>
|
|
342
|
-
);
|
|
343
|
-
}
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
### 2. Service Worker Communication
|
|
347
|
-
|
|
348
|
-
**Opportunity**: layouts components could communicate with nextjs service worker
|
|
349
|
-
|
|
350
|
-
```typescript
|
|
351
|
-
// layouts/PWA: Listen for SW update events
|
|
352
|
-
export function useServiceWorkerUpdate() {
|
|
353
|
-
const [updateAvailable, setUpdateAvailable] = useState(false);
|
|
354
|
-
|
|
355
|
-
useEffect(() => {
|
|
356
|
-
if ('serviceWorker' in navigator) {
|
|
357
|
-
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
|
358
|
-
setUpdateAvailable(true);
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
}, []);
|
|
362
|
-
|
|
363
|
-
return { updateAvailable };
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
// Usage in component
|
|
367
|
-
function UpdatePrompt() {
|
|
368
|
-
const { updateAvailable } = useServiceWorkerUpdate();
|
|
369
|
-
|
|
370
|
-
if (!updateAvailable) return null;
|
|
371
|
-
|
|
372
|
-
return (
|
|
373
|
-
<div className="fixed bottom-4 right-4">
|
|
374
|
-
<Button onClick={() => window.location.reload()}>
|
|
375
|
-
Update Available - Reload
|
|
376
|
-
</Button>
|
|
377
|
-
</div>
|
|
378
|
-
);
|
|
379
|
-
}
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
### 3. Shared Types
|
|
383
|
-
|
|
384
|
-
**Opportunity**: Share TypeScript types between packages
|
|
385
|
-
|
|
386
|
-
```typescript
|
|
387
|
-
// @djangocfg/pwa-types (new package)
|
|
388
|
-
export interface PWAManifest {
|
|
389
|
-
name: string;
|
|
390
|
-
short_name: string;
|
|
391
|
-
theme_color: string;
|
|
392
|
-
background_color: string;
|
|
393
|
-
display: 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser';
|
|
394
|
-
icons: ManifestIcon[];
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
export interface RuntimeCachingStrategy {
|
|
398
|
-
urlPattern: RegExp | string;
|
|
399
|
-
handler: 'CacheFirst' | 'NetworkFirst' | 'StaleWhileRevalidate';
|
|
400
|
-
options?: CachingOptions;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
export interface PushNotificationConfig {
|
|
404
|
-
vapidPublicKey: string;
|
|
405
|
-
subscribeEndpoint?: string;
|
|
406
|
-
}
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
Both packages import from shared types package.
|
|
410
|
-
|
|
411
|
-
### 4. CLI Tool Integration
|
|
412
|
-
|
|
413
|
-
**Opportunity**: Single CLI for PWA management
|
|
414
|
-
|
|
415
|
-
```bash
|
|
416
|
-
# Generate VAPID keys
|
|
417
|
-
pnpm pwa generate-vapid
|
|
418
|
-
|
|
419
|
-
# Validate PWA configuration
|
|
420
|
-
pnpm pwa validate
|
|
421
|
-
|
|
422
|
-
# Test push notifications
|
|
423
|
-
pnpm pwa test-push --endpoint http://localhost:3000
|
|
424
|
-
|
|
425
|
-
# Analyze PWA score
|
|
426
|
-
pnpm pwa audit
|
|
427
|
-
```
|
|
428
|
-
|
|
429
|
-
Could be implemented in `@djangocfg/nextjs` CLI.
|
|
430
|
-
|
|
431
|
-
---
|
|
432
|
-
|
|
433
|
-
## Strengths and Weaknesses
|
|
434
|
-
|
|
435
|
-
### layouts/PWA
|
|
436
|
-
|
|
437
|
-
**Strengths** ✅:
|
|
438
|
-
1. Complete UI/UX for installation flow
|
|
439
|
-
2. Excellent platform detection (iOS + Android)
|
|
440
|
-
3. Robust push notification handling
|
|
441
|
-
4. Great developer experience (error messages, debug mode)
|
|
442
|
-
5. Adaptive UI (drawer on mobile, modal on desktop)
|
|
443
|
-
6. Well-documented with examples
|
|
444
|
-
|
|
445
|
-
**Weaknesses** ⚠️:
|
|
446
|
-
1. No service worker generation
|
|
447
|
-
2. No manifest generation
|
|
448
|
-
3. Assumes external SW exists
|
|
449
|
-
4. No runtime caching utilities
|
|
450
|
-
5. Frontend-only (no backend integration examples)
|
|
451
|
-
|
|
452
|
-
**Best For**:
|
|
453
|
-
- Apps that need polished install prompts
|
|
454
|
-
- Apps with push notifications
|
|
455
|
-
- Custom PWA experiences
|
|
456
|
-
- When you already have a service worker
|
|
457
|
-
|
|
458
|
-
### nextjs/PWA
|
|
459
|
-
|
|
460
|
-
**Strengths** ✅:
|
|
461
|
-
1. Automatic service worker generation
|
|
462
|
-
2. Automatic manifest generation
|
|
463
|
-
3. Built-in runtime caching (Workbox)
|
|
464
|
-
4. Zero-config PWA setup
|
|
465
|
-
5. Build-time optimization
|
|
466
|
-
6. Precaching of static assets
|
|
467
|
-
|
|
468
|
-
**Weaknesses** ⚠️:
|
|
469
|
-
1. No UI components for installation
|
|
470
|
-
2. No push notification handling
|
|
471
|
-
3. Limited runtime utilities
|
|
472
|
-
4. Less control over SW behavior
|
|
473
|
-
5. No install prompt customization
|
|
474
|
-
|
|
475
|
-
**Best For**:
|
|
476
|
-
- Quick PWA setup
|
|
477
|
-
- Apps that need offline support
|
|
478
|
-
- Standard PWA requirements
|
|
479
|
-
- When you want automatic configuration
|
|
480
|
-
|
|
481
|
-
---
|
|
482
|
-
|
|
483
|
-
## Learning Opportunities
|
|
484
|
-
|
|
485
|
-
### What layouts can learn from nextjs
|
|
486
|
-
|
|
487
|
-
1. **Automatic Generation**
|
|
488
|
-
- Consider generating boilerplate code
|
|
489
|
-
- CLI tool for scaffolding
|
|
490
|
-
|
|
491
|
-
2. **Build-Time Validation**
|
|
492
|
-
- Validate VAPID keys at build time
|
|
493
|
-
- Check manifest exists
|
|
494
|
-
- Verify service worker registration
|
|
495
|
-
|
|
496
|
-
3. **Convention over Configuration**
|
|
497
|
-
- Sensible defaults
|
|
498
|
-
- Less boilerplate
|
|
499
|
-
|
|
500
|
-
4. **Service Worker Utilities**
|
|
501
|
-
- Provide optional SW helpers
|
|
502
|
-
- Runtime caching utilities
|
|
503
|
-
|
|
504
|
-
### What nextjs can learn from layouts
|
|
505
|
-
|
|
506
|
-
1. **UI Components**
|
|
507
|
-
- Provide default install prompt components
|
|
508
|
-
- Push notification UI
|
|
509
|
-
|
|
510
|
-
2. **Runtime Debugging**
|
|
511
|
-
- Better error messages
|
|
512
|
-
- Debug mode in production
|
|
513
|
-
- Diagnostic tools
|
|
514
|
-
|
|
515
|
-
3. **Platform Detection**
|
|
516
|
-
- Better iOS/Android detection
|
|
517
|
-
- Reliable standalone checking
|
|
518
|
-
|
|
519
|
-
4. **State Management**
|
|
520
|
-
- React Context for PWA state
|
|
521
|
-
- Hooks for common patterns
|
|
522
|
-
|
|
523
|
-
---
|
|
524
|
-
|
|
525
|
-
## Recommended Integration Pattern
|
|
526
|
-
|
|
527
|
-
### Complete PWA Stack
|
|
528
|
-
|
|
529
|
-
```
|
|
530
|
-
┌─────────────────────────────────────┐
|
|
531
|
-
│ User Experience (Frontend) │
|
|
532
|
-
│ │
|
|
533
|
-
│ layouts/PWA │
|
|
534
|
-
│ ├── Install Prompts (A2HSHint) │
|
|
535
|
-
│ ├── Push Notifications (PushPrompt)│
|
|
536
|
-
│ └── State Management (Context) │
|
|
537
|
-
└─────────────────────────────────────┘
|
|
538
|
-
↓ ↑
|
|
539
|
-
┌─────────────────────────────────────┐
|
|
540
|
-
│ Infrastructure (Build + Runtime) │
|
|
541
|
-
│ │
|
|
542
|
-
│ nextjs/PWA │
|
|
543
|
-
│ ├── Service Worker (Workbox) │
|
|
544
|
-
│ ├── Manifest Generation │
|
|
545
|
-
│ └── Runtime Caching │
|
|
546
|
-
└─────────────────────────────────────┘
|
|
547
|
-
↓ ↑
|
|
548
|
-
┌─────────────────────────────────────┐
|
|
549
|
-
│ Backend (API Routes) │
|
|
550
|
-
│ │
|
|
551
|
-
│ ├── /api/push/subscribe │
|
|
552
|
-
│ ├── /api/push/send │
|
|
553
|
-
│ └── Database (subscriptions) │
|
|
554
|
-
└─────────────────────────────────────┘
|
|
555
|
-
```
|
|
556
|
-
|
|
557
|
-
### Setup Checklist
|
|
558
|
-
|
|
559
|
-
**Step 1: Install dependencies**
|
|
560
|
-
```bash
|
|
561
|
-
pnpm add @djangocfg/nextjs @djangocfg/layouts
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
**Step 2: Configure nextjs/PWA (Build-Time)**
|
|
565
|
-
```js
|
|
566
|
-
// next.config.mjs
|
|
567
|
-
import withPWA from '@djangocfg/nextjs/pwa';
|
|
568
|
-
|
|
569
|
-
export default withPWA({
|
|
570
|
-
dest: 'public',
|
|
571
|
-
register: true,
|
|
572
|
-
skipWaiting: true,
|
|
573
|
-
manifest: {
|
|
574
|
-
name: 'My App',
|
|
575
|
-
short_name: 'App',
|
|
576
|
-
theme_color: '#000000',
|
|
577
|
-
display: 'standalone',
|
|
578
|
-
icons: [ /* ... */ ],
|
|
579
|
-
},
|
|
580
|
-
runtimeCaching: [ /* ... */ ],
|
|
581
|
-
});
|
|
582
|
-
```
|
|
583
|
-
|
|
584
|
-
**Step 3: Add layouts/PWA UI (Runtime)**
|
|
585
|
-
```tsx
|
|
586
|
-
// app/layout.tsx
|
|
587
|
-
import { PwaProvider } from '@djangocfg/layouts/snippets';
|
|
588
|
-
|
|
589
|
-
export default function RootLayout({ children }) {
|
|
590
|
-
return (
|
|
591
|
-
<html>
|
|
592
|
-
<body>
|
|
593
|
-
<PwaProvider
|
|
594
|
-
enabled
|
|
595
|
-
showInstallHint
|
|
596
|
-
pushNotifications={{
|
|
597
|
-
vapidPublicKey: process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY!,
|
|
598
|
-
subscribeEndpoint: '/api/push/subscribe',
|
|
599
|
-
}}
|
|
600
|
-
>
|
|
601
|
-
{children}
|
|
602
|
-
</PwaProvider>
|
|
603
|
-
</body>
|
|
604
|
-
</html>
|
|
605
|
-
);
|
|
606
|
-
}
|
|
607
|
-
```
|
|
608
|
-
|
|
609
|
-
**Step 4: Add Backend API Routes**
|
|
610
|
-
```typescript
|
|
611
|
-
// app/api/push/subscribe/route.ts
|
|
612
|
-
export async function POST(request: Request) {
|
|
613
|
-
const subscription = await request.json();
|
|
614
|
-
// Save to database
|
|
615
|
-
return Response.json({ success: true });
|
|
616
|
-
}
|
|
617
|
-
```
|
|
618
|
-
|
|
619
|
-
**Result**: Complete PWA with:
|
|
620
|
-
- ✅ Service worker (nextjs)
|
|
621
|
-
- ✅ Manifest (nextjs)
|
|
622
|
-
- ✅ Offline support (nextjs)
|
|
623
|
-
- ✅ Install UI (layouts)
|
|
624
|
-
- ✅ Push notifications (layouts)
|
|
625
|
-
- ✅ Backend persistence (custom)
|
|
626
|
-
|
|
627
|
-
---
|
|
628
|
-
|
|
629
|
-
## Future Opportunities
|
|
630
|
-
|
|
631
|
-
### 1. Unified PWA Package
|
|
632
|
-
|
|
633
|
-
**Vision**: Single package combining both
|
|
634
|
-
|
|
635
|
-
```
|
|
636
|
-
@djangocfg/pwa
|
|
637
|
-
├── Build-time (from nextjs/PWA)
|
|
638
|
-
│ ├── withPWA()
|
|
639
|
-
│ ├── Service Worker generation
|
|
640
|
-
│ └── Manifest generation
|
|
641
|
-
│
|
|
642
|
-
└── Runtime (from layouts/PWA)
|
|
643
|
-
├── UI Components
|
|
644
|
-
├── Hooks
|
|
645
|
-
└── Context
|
|
646
|
-
```
|
|
647
|
-
|
|
648
|
-
**Benefits**:
|
|
649
|
-
- One installation
|
|
650
|
-
- Unified configuration
|
|
651
|
-
- Shared types
|
|
652
|
-
- Better integration
|
|
653
|
-
|
|
654
|
-
### 2. PWA CLI Tool
|
|
655
|
-
|
|
656
|
-
**Vision**: Command-line tool for PWA management
|
|
657
|
-
|
|
658
|
-
```bash
|
|
659
|
-
pnpm create @djangocfg/pwa
|
|
660
|
-
# Interactive setup wizard
|
|
661
|
-
|
|
662
|
-
pnpm pwa generate-vapid
|
|
663
|
-
# Generate VAPID key pair
|
|
664
|
-
|
|
665
|
-
pnpm pwa validate
|
|
666
|
-
# Validate PWA configuration
|
|
667
|
-
|
|
668
|
-
pnpm pwa test
|
|
669
|
-
# Test PWA functionality locally
|
|
670
|
-
|
|
671
|
-
pnpm pwa audit
|
|
672
|
-
# Run Lighthouse PWA audit
|
|
673
|
-
```
|
|
674
|
-
|
|
675
|
-
### 3. PWA Dashboard
|
|
676
|
-
|
|
677
|
-
**Vision**: Admin dashboard for PWA analytics
|
|
678
|
-
|
|
679
|
-
```tsx
|
|
680
|
-
import { PWADashboard } from '@djangocfg/pwa/admin';
|
|
681
|
-
|
|
682
|
-
export default function AdminPage() {
|
|
683
|
-
return (
|
|
684
|
-
<PWADashboard
|
|
685
|
-
subscriptions={subscriptions}
|
|
686
|
-
installations={installations}
|
|
687
|
-
metrics={metrics}
|
|
688
|
-
/>
|
|
689
|
-
);
|
|
690
|
-
}
|
|
691
|
-
```
|
|
692
|
-
|
|
693
|
-
**Features**:
|
|
694
|
-
- View active push subscriptions
|
|
695
|
-
- Track install metrics
|
|
696
|
-
- Test push notifications
|
|
697
|
-
- Manage subscribers
|
|
698
|
-
|
|
699
|
-
---
|
|
700
|
-
|
|
701
|
-
## Conclusion
|
|
702
|
-
|
|
703
|
-
**layouts/PWA** and **nextjs/PWA** are **complementary**:
|
|
704
|
-
|
|
705
|
-
- **nextjs/PWA**: Infrastructure (service worker, manifest)
|
|
706
|
-
- **layouts/PWA**: User experience (install prompts, push notifications)
|
|
707
|
-
|
|
708
|
-
**Recommendation**: **Use both together** for complete PWA solution
|
|
709
|
-
|
|
710
|
-
**Next Steps**:
|
|
711
|
-
1. Document integration pattern
|
|
712
|
-
2. Create integration examples
|
|
713
|
-
3. Consider unified package for future
|
|
714
|
-
4. Share types between packages
|
|
715
|
-
|
|
716
|
-
**Current State**: Both packages production-ready, work well together
|
|
717
|
-
|
|
718
|
-
**Future**: Tighter integration possible, but not urgent
|