@ericrisco/rsc 3.3.1 → 3.4.0
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 +2 -2
- package/manifest.json +43 -22
- package/package.json +1 -1
- package/scripts/lib/default-skill-floor.js +5 -1
- package/scripts/lib/domains.js +2 -2
- package/scripts/lib/retired-skills.js +4 -0
- package/skills/design/SKILL.md +4 -3
- package/skills/design/evals/cases.yaml +2 -2
- package/skills/react/SKILL.md +2 -1
- package/skills/ux/SKILL.md +149 -0
- package/skills/ux/THIRD_PARTY.md +32 -0
- package/skills/ux/evals/cases.yaml +40 -0
- package/skills/ux/references/flows.md +124 -0
- package/skills/ux/upstream/UPSTREAM.json +59 -0
- package/skills/ux/upstream/ux-designer/GUIDE.md +180 -0
- package/skills/ux/upstream/ux-designer/LICENSE +21 -0
- package/skills/ux/upstream/ux-designer/references/01-core-principles.md +251 -0
- package/skills/ux/upstream/ux-designer/references/02-laws-of-ux.md +330 -0
- package/skills/ux/upstream/ux-designer/references/03-accessibility.md +411 -0
- package/skills/ux/upstream/ux-designer/references/04-visual-design.md +433 -0
- package/skills/ux/upstream/ux-designer/references/05-information-architecture.md +432 -0
- package/skills/ux/upstream/ux-designer/references/06-interaction-design.md +495 -0
- package/skills/ux/upstream/ux-designer/references/07-forms-and-inputs.md +491 -0
- package/skills/ux/upstream/ux-designer/references/08-mobile-ux.md +539 -0
- package/skills/ux/upstream/ux-designer/references/09-ux-writing.md +493 -0
- package/skills/ux/upstream/ux-designer/references/10-user-research.md +533 -0
- package/skills/ux/upstream/ux-designer/references/11-design-systems.md +618 -0
- package/skills/ux/upstream/ux-designer/references/12a-presence-awareness.md +395 -0
- package/skills/ux/upstream/ux-designer/references/12b-conflict-resolution-sync.md +420 -0
- package/skills/ux/upstream/ux-designer/references/13a-canvas-navigation.md +388 -0
- package/skills/ux/upstream/ux-designer/references/13b-canvas-objects-performance.md +559 -0
- package/skills/ux/upstream/ux-designer/references/14-ai-ux-patterns.md +511 -0
- package/skills/ux/upstream/ux-designer/references/15-ethical-design.md +419 -0
- package/skills/ux/upstream/ux-designer/references/16-onboarding.md +430 -0
- package/skills/ux/upstream/ux-designer/references/17-notifications.md +461 -0
- package/skills/ux/upstream/ux-designer/references/18-data-visualization.md +453 -0
- package/skills/ux/upstream/ux-designer/references/19-search-ux.md +479 -0
- package/skills/ux/upstream/ux-designer/references/20-emotional-design.md +382 -0
- package/skills/ux/upstream/ux-designer/references/21-data-tables.md +629 -0
- package/skills/ux/upstream/ux-designer/references/22-performance-ux.md +626 -0
- package/skills/ux/upstream/ux-designer/references/23-internationalization.md +347 -0
- package/skills/ux/upstream/ux-designer/references/24-voice-and-multimodal.md +308 -0
- package/skills/ux/upstream/ux-designer/references/25a-barcode-camera-scanning.md +342 -0
- package/skills/ux/upstream/ux-designer/references/25b-barcode-scanner-workflows.md +412 -0
- package/skills/ux/upstream/ux-designer/references/25c-barcode-display.md +277 -0
- package/skills/ux/upstream/ux-usability-foundations/GUIDE.md +285 -0
- package/skills/ux/upstream/ux-usability-foundations/LICENSE +21 -0
- package/skills/ux/upstream/ux-usability-foundations/references/anti-patterns.md +267 -0
- package/skills/ux/upstream/ux-usability-foundations/references/checklists.md +130 -0
- package/skills/ux/upstream/ux-usability-foundations/references/decision-prompts.md +340 -0
- package/skills/ux/upstream/ux-usability-foundations/references/principle-cards.md +449 -0
- package/targets/clone-bootstrap.mjs +1 -1
- package/skills/ui-engineering/SKILL.md +0 -113
- package/skills/ui-engineering/evals/cases.yaml +0 -38
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
# Notification & Attention Design
|
|
2
|
+
|
|
3
|
+
Notifications are a cross-cutting concern that affects every product. This reference covers notification types, delivery channels, attention management, and permission patterns for responsible notification design.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
|
|
9
|
+
- Notification Types
|
|
10
|
+
- Severity & Visual Hierarchy
|
|
11
|
+
- Delivery Channels
|
|
12
|
+
- Notification Center
|
|
13
|
+
- Attention Management
|
|
14
|
+
- Permission Requests
|
|
15
|
+
- Key Metrics
|
|
16
|
+
- Anti-Patterns
|
|
17
|
+
- Sources
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Notification Types
|
|
22
|
+
|
|
23
|
+
### By Purpose
|
|
24
|
+
|
|
25
|
+
| Type | Description | Priority | Example |
|
|
26
|
+
|------|-------------|----------|---------|
|
|
27
|
+
| **Transactional** | Result of a user action | High | "Order confirmed", "Payment received" |
|
|
28
|
+
| **Informational** | System updates or status | Medium | "Maintenance scheduled", "Export ready" |
|
|
29
|
+
| **Social** | Activity from other users | Medium | "Alex commented on your post" |
|
|
30
|
+
| **Promotional** | Marketing or upsell | Low | "Try our new feature", "Upgrade plan" |
|
|
31
|
+
| **Alert** | Urgent system or security | Critical | "Unusual sign-in detected", "Server down" |
|
|
32
|
+
|
|
33
|
+
### By Urgency
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
Critical ████████████ Requires immediate action (security, data loss)
|
|
37
|
+
High █████████░░░ Important, time-sensitive (mentions, assignments)
|
|
38
|
+
Medium ██████░░░░░░ Relevant but not urgent (comments, updates)
|
|
39
|
+
Low ███░░░░░░░░░ Nice to know (tips, promotions)
|
|
40
|
+
Info █░░░░░░░░░░░ Background context (changelog, analytics)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Severity & Visual Hierarchy
|
|
46
|
+
|
|
47
|
+
### Standard Severity Levels
|
|
48
|
+
|
|
49
|
+
```css
|
|
50
|
+
/* Critical — Blocking issue, requires immediate attention */
|
|
51
|
+
.alert-critical {
|
|
52
|
+
background: #fef2f2;
|
|
53
|
+
border-left: 4px solid #dc2626;
|
|
54
|
+
color: #991b1b;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* Warning — Potential issue, user should be aware */
|
|
58
|
+
.alert-warning {
|
|
59
|
+
background: #fffbeb;
|
|
60
|
+
border-left: 4px solid #f59e0b;
|
|
61
|
+
color: #92400e;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* Success — Positive confirmation */
|
|
65
|
+
.alert-success {
|
|
66
|
+
background: #f0fdf4;
|
|
67
|
+
border-left: 4px solid #16a34a;
|
|
68
|
+
color: #166534;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* Info — Neutral information */
|
|
72
|
+
.alert-info {
|
|
73
|
+
background: #eff6ff;
|
|
74
|
+
border-left: 4px solid #3b82f6;
|
|
75
|
+
color: #1e40af;
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Visual Priority
|
|
80
|
+
|
|
81
|
+
| Element | Critical | Warning | Info | Success |
|
|
82
|
+
|---------|----------|---------|------|---------|
|
|
83
|
+
| Icon | ⛔ / 🔴 | ⚠️ / 🟡 | ℹ️ / 🔵 | ✅ / 🟢 |
|
|
84
|
+
| Color | Red | Yellow/Amber | Blue | Green |
|
|
85
|
+
| Position | Modal/top banner | Top banner | Inline/toast | Toast |
|
|
86
|
+
| Sound | Optional alert | None | None | None |
|
|
87
|
+
| Persistence | Until resolved | Until dismissed | Auto-dismiss | Auto-dismiss |
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Delivery Channels
|
|
92
|
+
|
|
93
|
+
### Channel Selection Guide
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
Urgency
|
|
97
|
+
High ──────────── Low
|
|
98
|
+
│ │
|
|
99
|
+
Sync │ Modal Banner │
|
|
100
|
+
(blocking) │ Alert Inline │
|
|
101
|
+
│ │
|
|
102
|
+
│ Push Email │
|
|
103
|
+
Async │ Toast Badge │
|
|
104
|
+
(non-block) │ SMS In-app feed │
|
|
105
|
+
│ │
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### In-App Notifications
|
|
109
|
+
|
|
110
|
+
#### Banners (Persistent)
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
┌───────────────────────────────────────────────────┐
|
|
114
|
+
│ ⚠️ Your trial expires in 3 days. [Upgrade now] [✕] │
|
|
115
|
+
└───────────────────────────────────────────────────┘
|
|
116
|
+
┌─────────────────── Page Content ──────────────────┐
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
- Fixed at top or bottom of viewport
|
|
120
|
+
- Persist until dismissed or condition resolved
|
|
121
|
+
- Use for: system-wide announcements, degraded service, account alerts
|
|
122
|
+
- Include clear action button and dismiss option
|
|
123
|
+
- Maximum 1-2 banners visible at a time
|
|
124
|
+
|
|
125
|
+
#### Toasts / Snackbars
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
┌──────────────────────────┐
|
|
129
|
+
│ ✅ Document saved │
|
|
130
|
+
│ [Undo] [✕] │
|
|
131
|
+
└──────────────────────────┘
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Duration guidelines:**
|
|
135
|
+
- Short messages (no action): 4 seconds
|
|
136
|
+
- Messages with action button: 6-8 seconds
|
|
137
|
+
- Error messages: 8-10 seconds or until dismissed
|
|
138
|
+
- Never auto-dismiss critical errors
|
|
139
|
+
|
|
140
|
+
**Placement:**
|
|
141
|
+
- Bottom-center or bottom-right (most common)
|
|
142
|
+
- Top-center for important alerts
|
|
143
|
+
- Consistent position throughout the app
|
|
144
|
+
- Away from primary interaction areas
|
|
145
|
+
|
|
146
|
+
**Stacking:**
|
|
147
|
+
```
|
|
148
|
+
┌──────────────────────────────┐
|
|
149
|
+
│ ✅ File uploaded │ ← newest
|
|
150
|
+
└──────────────────────────────┘
|
|
151
|
+
┌──────────────────────────────┐
|
|
152
|
+
│ ℹ️ 2 team members online │ ← older
|
|
153
|
+
└──────────────────────────────┘
|
|
154
|
+
|
|
155
|
+
Max stack: 3 toasts visible
|
|
156
|
+
Older toasts slide out or collapse
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
- Stack newest on top
|
|
160
|
+
- Maximum 3 visible at once
|
|
161
|
+
- Older toasts auto-dismiss to make room
|
|
162
|
+
- All toasts dismissible with close button or swipe
|
|
163
|
+
|
|
164
|
+
#### Badges
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
┌────────────────────────────────────────┐
|
|
168
|
+
│ [🔔 3] [📨 12] [👤] │
|
|
169
|
+
└────────────────────────────────────────┘
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Design rules:**
|
|
173
|
+
- Numeric badge: 1-99, then "99+" for overflow
|
|
174
|
+
- Dot badge: for "something new" without specific count
|
|
175
|
+
- Position: top-right of the icon
|
|
176
|
+
- Color: red for requiring attention, blue/gray for informational
|
|
177
|
+
- Clear on interaction (opening the relevant section)
|
|
178
|
+
- Animate on increment (subtle scale pulse)
|
|
179
|
+
|
|
180
|
+
#### Modals / Dialogs
|
|
181
|
+
|
|
182
|
+
Reserve for critical interruptions that require immediate user decision.
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
┌─────────────────────────────────────────┐
|
|
186
|
+
│ ⚠️ Unsaved Changes │
|
|
187
|
+
│ │
|
|
188
|
+
│ You have unsaved changes that will be │
|
|
189
|
+
│ lost if you leave this page. │
|
|
190
|
+
│ │
|
|
191
|
+
│ [Discard Changes] [Save & Continue] │
|
|
192
|
+
└──────────────────────────────────────────┘
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
- Only for actions that require a decision
|
|
196
|
+
- Never for informational messages (use toast/banner instead)
|
|
197
|
+
- Always provide a clear way to dismiss (Esc, close button, outside click)
|
|
198
|
+
- Maximum 1 modal at a time (never stack modals)
|
|
199
|
+
- Include a clear primary action
|
|
200
|
+
|
|
201
|
+
#### Inline Notifications
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
┌─────────────────────────────────────────┐
|
|
205
|
+
│ Email: [user@example.com ] │
|
|
206
|
+
│ ⚠️ This email is already in use. │
|
|
207
|
+
│ [Sign in instead?] │
|
|
208
|
+
└─────────────────────────────────────────┘
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
- Placed directly next to the relevant content
|
|
212
|
+
- Contextual and specific to the user's action
|
|
213
|
+
- Best for: form validation, field-level errors, contextual tips
|
|
214
|
+
- Don't require dismissal (disappear when issue is resolved)
|
|
215
|
+
|
|
216
|
+
### External Channels
|
|
217
|
+
|
|
218
|
+
#### Push Notifications
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
┌─────────────────────────────────────────┐
|
|
222
|
+
│ 🔔 AppName now │
|
|
223
|
+
│ Alex commented on "Q4 Report" │
|
|
224
|
+
│ "Great analysis! Can we discuss the..." │
|
|
225
|
+
└─────────────────────────────────────────┘
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
- Ask permission contextually (not on first visit)
|
|
229
|
+
- Group related notifications (3+ from same thread → summary)
|
|
230
|
+
- Deep-link to the relevant content
|
|
231
|
+
- Rich notifications: image previews, action buttons
|
|
232
|
+
- Respect quiet hours (system settings or app-level)
|
|
233
|
+
|
|
234
|
+
#### Email Notifications
|
|
235
|
+
|
|
236
|
+
- Batch non-urgent notifications (daily/weekly digest)
|
|
237
|
+
- Include unsubscribe link in every email (CAN-SPAM, GDPR)
|
|
238
|
+
- One-click unsubscribe header (RFC 8058)
|
|
239
|
+
- Clear sender name and subject line
|
|
240
|
+
- Deep-link to specific content in the app
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Notification Center
|
|
245
|
+
|
|
246
|
+
### Inbox Pattern
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
┌─ Notifications ─────────────────────────┐
|
|
250
|
+
│ [All] [Unread (5)] [Mentions] │
|
|
251
|
+
│ │
|
|
252
|
+
│ Today │
|
|
253
|
+
│ ┌────────────────────────────────────┐ │
|
|
254
|
+
│ │ 🔵 Alex commented on "Q4 Report" │ │
|
|
255
|
+
│ │ "Looks great! One question..." │ │
|
|
256
|
+
│ │ 2 hours ago [···] │ │
|
|
257
|
+
│ ├────────────────────────────────────┤ │
|
|
258
|
+
│ │ 🔵 Build #142 passed │ │
|
|
259
|
+
│ │ main branch — all tests green │ │
|
|
260
|
+
│ │ 3 hours ago [···] │ │
|
|
261
|
+
│ ├────────────────────────────────────┤ │
|
|
262
|
+
│ │ Sarah shared "Design Brief" │ │
|
|
263
|
+
│ │ 5 hours ago [···] │ │
|
|
264
|
+
│ └────────────────────────────────────┘ │
|
|
265
|
+
│ │
|
|
266
|
+
│ Yesterday │
|
|
267
|
+
│ ┌────────────────────────────────────┐ │
|
|
268
|
+
│ │ Invoice #1234 paid │ │
|
|
269
|
+
│ │ Yesterday at 4:32 PM [···] │ │
|
|
270
|
+
│ └────────────────────────────────────┘ │
|
|
271
|
+
│ │
|
|
272
|
+
│ [Mark all as read] │
|
|
273
|
+
└──────────────────────────────────────────┘
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
**Features:**
|
|
277
|
+
- Read/unread visual distinction (dot, bold, background color)
|
|
278
|
+
- Grouping by time (Today, Yesterday, This week, Older)
|
|
279
|
+
- Filter tabs (All, Unread, Mentions, specific categories)
|
|
280
|
+
- Bulk actions: mark all as read, clear all
|
|
281
|
+
- Individual actions: mark read/unread, mute thread, delete
|
|
282
|
+
- Clicking notification navigates to relevant content
|
|
283
|
+
- Infinite scroll with loading states
|
|
284
|
+
- "You're all caught up" message when empty
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Attention Management
|
|
289
|
+
|
|
290
|
+
### Interruption Budget
|
|
291
|
+
|
|
292
|
+
Not all notifications deserve equal interruption.
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
Daily interruption budget (suggested maximums):
|
|
296
|
+
├── Critical alerts: No limit (safety/security)
|
|
297
|
+
├── High-priority (mentions, assignments): 10-15
|
|
298
|
+
├── Medium (comments, updates): Batched 2-3x/day
|
|
299
|
+
├── Low (tips, promotions): 1/day maximum
|
|
300
|
+
└── Passive (badges, feed): Zero interruption
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Do Not Disturb
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
┌─ Focus Mode ────────────────────────────┐
|
|
307
|
+
│ │
|
|
308
|
+
│ [🔕 Do Not Disturb] Until: [1 hour ▾] │
|
|
309
|
+
│ │
|
|
310
|
+
│ Allow through: │
|
|
311
|
+
│ [✓] Direct mentions │
|
|
312
|
+
│ [✓] Critical system alerts │
|
|
313
|
+
│ [ ] Comments on my items │
|
|
314
|
+
│ [ ] Team updates │
|
|
315
|
+
│ │
|
|
316
|
+
│ Schedule: │
|
|
317
|
+
│ [ ] Auto-enable outside work hours │
|
|
318
|
+
│ Work hours: [9:00] - [17:00] │
|
|
319
|
+
│ │
|
|
320
|
+
│ [Save] │
|
|
321
|
+
└──────────────────────────────────────────┘
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Notification Preferences
|
|
325
|
+
|
|
326
|
+
```
|
|
327
|
+
┌─ Notification Settings ─────────────────┐
|
|
328
|
+
│ │
|
|
329
|
+
│ Channel In-app Push Email │
|
|
330
|
+
│ ─────────────────────────────────────── │
|
|
331
|
+
│ Mentions ✓ ✓ ✓ │
|
|
332
|
+
│ Comments ✓ ✓ ○ │
|
|
333
|
+
│ Updates ✓ ○ ○ │
|
|
334
|
+
│ Marketing ○ ○ ○ │
|
|
335
|
+
│ │
|
|
336
|
+
│ ✓ = enabled ○ = disabled │
|
|
337
|
+
│ │
|
|
338
|
+
│ Email digest: [Weekly ▾] │
|
|
339
|
+
│ │
|
|
340
|
+
│ [Save preferences] │
|
|
341
|
+
└──────────────────────────────────────────┘
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
- Per-category, per-channel control
|
|
345
|
+
- Sensible defaults (not everything on)
|
|
346
|
+
- Email digest option for batching
|
|
347
|
+
- Quick "mute all" toggle
|
|
348
|
+
- Accessible from notification center and settings
|
|
349
|
+
|
|
350
|
+
### Batching & Grouping
|
|
351
|
+
|
|
352
|
+
```
|
|
353
|
+
Instead of 5 separate notifications:
|
|
354
|
+
"Alex commented on Project X"
|
|
355
|
+
"Alex commented on Project X"
|
|
356
|
+
"Sarah commented on Project X"
|
|
357
|
+
"Alex commented on Project X"
|
|
358
|
+
"Jordan commented on Project X"
|
|
359
|
+
|
|
360
|
+
Send 1 grouped notification:
|
|
361
|
+
"4 new comments on Project X from Alex, Sarah, and Jordan"
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
- Group by thread/topic, not by user
|
|
365
|
+
- Show count and participant summary
|
|
366
|
+
- Batch non-urgent notifications (5-15 minute window)
|
|
367
|
+
- Expand to individual items on click
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Permission Requests
|
|
372
|
+
|
|
373
|
+
### Just-in-Time Permissions
|
|
374
|
+
|
|
375
|
+
```
|
|
376
|
+
❌ On first visit:
|
|
377
|
+
"AppName wants to send you notifications"
|
|
378
|
+
[Don't Allow] [Allow]
|
|
379
|
+
|
|
380
|
+
✅ In context, when relevant:
|
|
381
|
+
┌─────────────────────────────────────────┐
|
|
382
|
+
│ Want to know when someone replies? │
|
|
383
|
+
│ │
|
|
384
|
+
│ Get notified when team members │
|
|
385
|
+
│ respond to your comments. │
|
|
386
|
+
│ │
|
|
387
|
+
│ [Enable Notifications] [Not now] │
|
|
388
|
+
└─────────────────────────────────────────┘
|
|
389
|
+
→ Then triggers the browser permission prompt
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### Pre-Permission Pattern
|
|
393
|
+
|
|
394
|
+
Before triggering the system permission dialog:
|
|
395
|
+
|
|
396
|
+
1. **Explain value**: Why the user benefits from this permission
|
|
397
|
+
2. **Show in context**: When the permission is relevant to what they're doing
|
|
398
|
+
3. **Custom prompt first**: Your own UI before the system dialog
|
|
399
|
+
4. **Respect "not now"**: Don't ask again for at least 30 days
|
|
400
|
+
5. **Never on first visit**: Wait until user has experienced product value
|
|
401
|
+
|
|
402
|
+
### Permission Denied Recovery
|
|
403
|
+
|
|
404
|
+
```
|
|
405
|
+
When user denied permission:
|
|
406
|
+
┌─────────────────────────────────────────┐
|
|
407
|
+
│ ℹ️ Notifications are disabled │
|
|
408
|
+
│ │
|
|
409
|
+
│ To enable notifications: │
|
|
410
|
+
│ 1. Click the lock icon in your browser │
|
|
411
|
+
│ 2. Find "Notifications" │
|
|
412
|
+
│ 3. Change to "Allow" │
|
|
413
|
+
│ │
|
|
414
|
+
│ [Show me how] │
|
|
415
|
+
└─────────────────────────────────────────┘
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
- Provide clear instructions to re-enable in browser/OS settings
|
|
419
|
+
- Don't repeatedly nag about denied permissions
|
|
420
|
+
- Offer email as a fallback channel
|
|
421
|
+
- Show relevant instructions per browser/platform
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
## Key Metrics
|
|
426
|
+
|
|
427
|
+
| Metric | Target | Context |
|
|
428
|
+
|--------|--------|---------|
|
|
429
|
+
| Push opt-in rate | > 50% | Permission acceptance |
|
|
430
|
+
| Notification open rate | > 15% | Push engagement |
|
|
431
|
+
| Email unsubscribe rate | < 0.5%/email | List health |
|
|
432
|
+
| Toast dismissal rate | Track | Too many = too noisy |
|
|
433
|
+
| Notification → action | > 25% | Relevance indicator |
|
|
434
|
+
| Permission ask timing | After activation | Not on first visit |
|
|
435
|
+
| DND usage | Monitor | High = too noisy overall |
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
## Anti-Patterns
|
|
440
|
+
|
|
441
|
+
1. **Permission on first visit** — Asking for push permission before user sees value
|
|
442
|
+
2. **Notification carpet bombing** — Sending every event as a push notification
|
|
443
|
+
3. **No notification preferences** — All-or-nothing notification control
|
|
444
|
+
4. **Stacking modals** — Multiple dialogs requiring sequential dismissal
|
|
445
|
+
5. **Auto-dismissing errors** — Critical errors that disappear before user reads them
|
|
446
|
+
6. **Same urgency for everything** — Treating promotions like security alerts
|
|
447
|
+
7. **No grouping** — 10 individual notifications for 10 comments on the same thread
|
|
448
|
+
8. **Notification-only features** — Actions only accessible through notification center
|
|
449
|
+
9. **Dark pattern nudging** — "You have 0 notifications" as a growth hack
|
|
450
|
+
10. **Ignoring quiet hours** — Sending push notifications at 3 AM
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
## Sources
|
|
455
|
+
|
|
456
|
+
- [Material Design: Notifications](https://m3.material.io/foundations/content-design/notifications) — Component patterns
|
|
457
|
+
- [Apple HIG: Notifications](https://developer.apple.com/design/human-interface-guidelines/notifications) — Platform guidelines
|
|
458
|
+
- [Nielsen Norman Group: Notification UX](https://www.nngroup.com/articles/push-notification/) — Research
|
|
459
|
+
- [Intercom: Notification Design](https://www.intercom.com/blog/) — SaaS patterns
|
|
460
|
+
- [Web Push Protocol](https://web.dev/articles/push-notifications-overview) — Technical implementation
|
|
461
|
+
- [RFC 8058](https://datatracker.ietf.org/doc/html/rfc8058) — One-click unsubscribe
|