vybekiit 0.7.4 → 0.7.7
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/dist/bin.js +10483 -1704
- package/dist/global-skills/aws-cdk/SKILL.md +2 -1
- package/dist/global-skills/aws-cloudformation/SKILL.md +2 -1
- package/dist/global-skills/aws-serverless/SKILL.md +45 -44
- package/dist/global-skills/aws-serverless/assets/powertools-handler.py +2 -1
- package/dist/global-skills/aws-serverless/references/api-gateway.md +50 -470
- package/dist/global-skills/aws-serverless/references/architecture.md +47 -186
- package/dist/global-skills/aws-serverless/references/concurrency.md +44 -158
- package/dist/global-skills/aws-serverless/references/deployment.md +1 -1
- package/dist/global-skills/aws-serverless/references/event-sources.md +72 -391
- package/dist/global-skills/aws-serverless/references/lambda.md +69 -428
- package/dist/global-skills/aws-serverless/references/orchestration.md +65 -384
- package/dist/global-skills/aws-serverless/references/production.md +78 -415
- package/dist/global-skills/aws-serverless/references/troubleshooting.md +92 -619
- package/dist/global-skills/claimable-postgres/SKILL.md +60 -49
- package/dist/global-skills/design-my-data/SKILL.md +2 -0
- package/dist/global-skills/eas-app-stores/SKILL.md +8 -0
- package/dist/global-skills/eas-app-stores/references/play-store.md +2 -0
- package/dist/global-skills/eas-hosting/SKILL.md +8 -0
- package/dist/global-skills/eas-observe/SKILL.md +30 -8
- package/dist/global-skills/eas-observe/agents/openai.yaml +1 -1
- package/dist/global-skills/eas-observe/references/metrics.md +54 -3
- package/dist/global-skills/eas-observe/references/queries.md +78 -17
- package/dist/global-skills/eas-observe/references/setup.md +164 -5
- package/dist/global-skills/eas-observe/references/third-party.md +136 -0
- package/dist/global-skills/eas-simulator/SKILL.md +63 -11
- package/dist/global-skills/eas-simulator/references/controllers.md +21 -2
- package/dist/global-skills/eas-simulator/references/run-your-app.md +16 -11
- package/dist/global-skills/eas-simulator/references/troubleshooting.md +8 -5
- package/dist/global-skills/eas-update-insights/SKILL.md +8 -0
- package/dist/global-skills/eas-workflows/SKILL.md +15 -10
- package/dist/global-skills/eas-workflows/scripts/package.json +2 -7
- package/dist/global-skills/email-best-practices/.github/workflows/sync-skills.yml +30 -0
- package/dist/global-skills/email-best-practices/README.md +63 -0
- package/dist/global-skills/email-best-practices/references/accessibility.md +189 -0
- package/dist/global-skills/email-best-practices/references/compliance.md +125 -0
- package/dist/global-skills/email-best-practices/references/deliverability.md +121 -0
- package/dist/global-skills/email-best-practices/references/email-capture.md +129 -0
- package/dist/global-skills/email-best-practices/references/email-types.md +173 -0
- package/dist/global-skills/email-best-practices/references/list-management.md +157 -0
- package/dist/global-skills/email-best-practices/references/marketing-emails.md +115 -0
- package/dist/global-skills/email-best-practices/references/sending-reliability.md +155 -0
- package/dist/global-skills/email-best-practices/references/transactional-email-catalog.md +418 -0
- package/dist/global-skills/email-best-practices/references/transactional-emails.md +92 -0
- package/dist/global-skills/email-best-practices/references/webhooks-events.md +167 -0
- package/dist/global-skills/email-best-practices/tests/README.md +35 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/01-spam-deliverability.md +46 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/02-multi-region-compliance.md +48 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/03-retry-idempotency.md +36 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/04-webhook-bounce-handling.md +52 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/05-new-saas-email-plan.md +51 -0
- package/dist/global-skills/expo-animation/LICENSE +21 -0
- package/dist/global-skills/expo-animation/RECIPES.md +385 -0
- package/dist/global-skills/expo-animation/SKILL.md +267 -0
- package/dist/global-skills/expo-animation/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-app-clip/SKILL.md +8 -0
- package/dist/global-skills/expo-brownfield/SKILL.md +8 -0
- package/dist/global-skills/expo-brownfield/references/brownfield-isolated.md +53 -4
- package/dist/global-skills/expo-data-fetching/SKILL.md +8 -0
- package/dist/global-skills/expo-design-system/SKILL.md +356 -0
- package/dist/global-skills/expo-design-system/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-design-system/references/audit.md +185 -0
- package/dist/global-skills/expo-dev-client/SKILL.md +8 -0
- package/dist/global-skills/expo-dom/SKILL.md +8 -0
- package/dist/global-skills/expo-examples/SKILL.md +8 -0
- package/dist/global-skills/expo-migrate-module/SKILL.md +113 -0
- package/dist/global-skills/expo-migrate-module/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-migrate-module/references/compatibility.md +73 -0
- package/dist/global-skills/expo-migrate-module/references/example.md +212 -0
- package/dist/global-skills/expo-migrate-module/references/migration-map.md +306 -0
- package/dist/global-skills/expo-module/SKILL.md +11 -1
- package/dist/global-skills/expo-native-ui/SKILL.md +8 -0
- package/dist/global-skills/expo-project-structure/SKILL.md +114 -0
- package/dist/global-skills/expo-project-structure/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-router/SKILL.md +8 -0
- package/dist/global-skills/expo-skill-feedback/SKILL.md +66 -33
- package/dist/global-skills/expo-skill-feedback/agents/openai.yaml +2 -2
- package/dist/global-skills/expo-tailwind-setup/SKILL.md +8 -0
- package/dist/global-skills/expo-ui/SKILL.md +8 -0
- package/dist/global-skills/expo-upgrade/SKILL.md +15 -1
- package/dist/global-skills/expo-web-to-native/SKILL.md +8 -0
- package/dist/global-skills/extension-to-functions-codebase/SKILL.md +129 -0
- package/dist/global-skills/extension-to-functions-codebase/references/configuration-migration.md +161 -0
- package/dist/global-skills/extension-to-functions-codebase/references/destructuring-shim.md +122 -0
- package/dist/global-skills/extension-to-functions-codebase/references/signature-mapping.md +84 -0
- package/dist/global-skills/firebase-ai-logic-basics/SKILL.md +61 -19
- package/dist/global-skills/firebase-ai-logic-basics/references/flutter_setup.md +6 -3
- package/dist/global-skills/firebase-app-hosting-basics/SKILL.md +5 -1
- package/dist/global-skills/firebase-auth-basics/SKILL.md +4 -2
- package/dist/global-skills/firebase-basics/SKILL.md +5 -5
- package/dist/global-skills/firebase-crashlytics/SKILL.md +2 -0
- package/dist/global-skills/firebase-data-connect/SKILL.md +2 -0
- package/dist/global-skills/firebase-firestore/SKILL.md +3 -6
- package/dist/global-skills/firebase-hosting-basics/SKILL.md +4 -1
- package/dist/global-skills/firebase-remote-config-basics/SKILL.md +5 -1
- package/dist/global-skills/firebase-security-rules-auditor/SKILL.md +4 -1
- package/dist/global-skills/harden/SKILL.md +2 -1
- package/dist/global-skills/instrument-feature-flags/SKILL.md +1 -0
- package/dist/global-skills/instrument-feature-flags/references/COMMANDMENTS.md +5 -0
- package/dist/global-skills/instrument-feature-flags/references/adding-feature-flag-code.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/android.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/api.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/best-practices.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/django.md +38 -5
- package/dist/global-skills/instrument-feature-flags/references/dotnet.md +10 -4
- package/dist/global-skills/instrument-feature-flags/references/elixir.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/flask.md +17 -5
- package/dist/global-skills/instrument-feature-flags/references/flutter.md +7 -5
- package/dist/global-skills/instrument-feature-flags/references/go.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ios.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/java.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/laravel.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/next-js.md +74 -8
- package/dist/global-skills/instrument-feature-flags/references/nodejs.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/php.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/python.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/react-native.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/react.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ruby-on-rails.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ruby.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/rust.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/usage.md +41 -4
- package/dist/global-skills/instrument-feature-flags/references/web.md +7 -5
- package/dist/global-skills/instrument-product-analytics/SKILL.md +2 -1
- package/dist/global-skills/instrument-product-analytics/references/COMMANDMENTS.md +5 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-hybrid.md +12 -14
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-ssr.md +25 -21
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-django.md +75 -55
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-fastapi.md +3 -6
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-flask.md +26 -16
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-nuxt-3-6.md +8 -5
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-nuxt-4.md +4 -4
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-react-router-7-framework.md +3 -3
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby-on-rails.md +8 -4
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-tanstack-start.md +20 -8
- package/dist/global-skills/instrument-product-analytics/references/android.md +46 -4
- package/dist/global-skills/instrument-product-analytics/references/angular.md +41 -5
- package/dist/global-skills/instrument-product-analytics/references/astro.md +41 -5
- package/dist/global-skills/instrument-product-analytics/references/configuration.md +7 -4
- package/dist/global-skills/instrument-product-analytics/references/django.md +38 -5
- package/dist/global-skills/instrument-product-analytics/references/dotnet.md +10 -4
- package/dist/global-skills/instrument-product-analytics/references/elixir.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/flask.md +17 -5
- package/dist/global-skills/instrument-product-analytics/references/flutter.md +49 -4
- package/dist/global-skills/instrument-product-analytics/references/go.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/identify-users.md +38 -7
- package/dist/global-skills/instrument-product-analytics/references/ios.md +14 -4
- package/dist/global-skills/instrument-product-analytics/references/laravel.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/next-js.md +74 -8
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js-3-6.md +39 -7
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js.md +40 -4
- package/dist/global-skills/instrument-product-analytics/references/php.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +21 -17
- package/dist/global-skills/instrument-product-analytics/references/python.md +15 -5
- package/dist/global-skills/instrument-product-analytics/references/react-native.md +41 -7
- package/dist/global-skills/instrument-product-analytics/references/react-router-v6.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-data-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-declarative-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-framework-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/ruby-on-rails.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/ruby.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/svelte.md +42 -6
- package/dist/global-skills/instrument-product-analytics/references/tanstack-start.md +31 -7
- package/dist/global-skills/instrument-product-analytics/references/usage.md +41 -4
- package/dist/global-skills/instrument-product-analytics/references/vue-js.md +42 -6
- package/dist/global-skills/manifest.json +6 -1
- package/dist/global-skills/neon/SKILL.md +235 -121
- package/dist/global-skills/neon-ai-gateway/SKILL.md +95 -16
- package/dist/global-skills/neon-functions/SKILL.md +242 -152
- package/dist/global-skills/neon-functions/references/ai-sdk.md +9 -3
- package/dist/global-skills/neon-functions/references/mastra-studio.md +1 -1
- package/dist/global-skills/neon-functions/references/mcp.md +13 -4
- package/dist/global-skills/neon-functions/references/sentry.md +165 -52
- package/dist/global-skills/neon-functions/references/sse.md +23 -6
- package/dist/global-skills/neon-object-storage/SKILL.md +40 -16
- package/dist/global-skills/neon-postgres/SKILL.md +63 -262
- package/dist/global-skills/neon-postgres-branches/SKILL.md +61 -50
- package/dist/global-skills/neon-postgres-egress-optimizer/SKILL.md +22 -3
- package/dist/global-skills/resend/SKILL.md +6 -6
- package/dist/global-skills/resend/references/automations.md +2 -2
- package/dist/global-skills/resend/references/broadcasts.md +11 -3
- package/dist/global-skills/resend/references/domains.md +25 -3
- package/dist/global-skills/resend/references/installation.md +7 -7
- package/dist/global-skills/setup-payments/SKILL.md +4 -5
- package/dist/global-skills/stripe-best-practices/SKILL.md +32 -7
- package/dist/global-skills/stripe-best-practices/references/billing.md +11 -1
- package/dist/global-skills/stripe-best-practices/references/payments.md +23 -2
- package/dist/global-skills/stripe-best-practices/references/security.md +21 -11
- package/dist/global-skills/stripe-best-practices/references/tax.md +116 -11
- package/dist/global-skills/supabase/CHANGELOG.md +25 -0
- package/dist/global-skills/supabase/SKILL.md +5 -1
- package/dist/global-skills/supabase-postgres-best-practices/CHANGELOG.md +30 -0
- package/dist/global-skills/supabase-postgres-best-practices/SKILL.md +1 -1
- package/dist/global-skills/use-kit-mcp/SKILL.md +5 -5
- package/dist/global-skills/use-railway/SKILL.md +4 -4
- package/dist/global-skills/use-railway/references/iac.md +206 -57
- package/dist/global-skills/use-railway/scripts/railway-api.sh +7 -2
- package/dist/global-skills/xcode-project-setup/SKILL.md +2 -0
- package/package.json +12 -9
- package/LICENSE.md +0 -47
- package/dist/global-skills/eas-workflows/scripts/validate.js +0 -84
- package/dist/global-skills/expo-skill-feedback/scripts/skill-feedback.cjs +0 -118
- package/dist/global-skills/neon-functions/references/hono-websockets.md +0 -145
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Email Deliverability
|
|
2
|
+
|
|
3
|
+
Maximizing the chances that your emails are delivered successfully to the recipients.
|
|
4
|
+
|
|
5
|
+
## Email Authentication
|
|
6
|
+
|
|
7
|
+
**Required by Gmail/Yahoo/Microsoft** - unauthenticated emails will be rejected or spam-filtered.
|
|
8
|
+
|
|
9
|
+
### SPF (Sender Policy Framework)
|
|
10
|
+
|
|
11
|
+
Specifies which servers can send email for your domain.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
v=spf1 include:amazonses.com ~all
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- Add TXT record to DNS
|
|
18
|
+
- Use `~all` (soft fail)
|
|
19
|
+
|
|
20
|
+
### DKIM (DomainKeys Identified Mail)
|
|
21
|
+
|
|
22
|
+
Cryptographic signature proving email authenticity.
|
|
23
|
+
|
|
24
|
+
- Your email service will provide you with a TXT record
|
|
25
|
+
|
|
26
|
+
### DMARC
|
|
27
|
+
|
|
28
|
+
Policy for handling SPF/DKIM failures + reporting.
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
v=DMARC1; p=none; rua=mailto:dmarc@example.com
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Rollout:** `p=none` (monitor) → `p=quarantine; pct=25` → `p=reject`
|
|
35
|
+
|
|
36
|
+
Learn more: https://resend.com/blog/dmarc-policy-modes
|
|
37
|
+
|
|
38
|
+
### Verify Your Setup
|
|
39
|
+
|
|
40
|
+
Check DNS records directly:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# SPF record
|
|
44
|
+
dig TXT example.com +short
|
|
45
|
+
|
|
46
|
+
# DKIM record (replace 'resend' with your selector)
|
|
47
|
+
dig TXT resend._domainkey.example.com +short
|
|
48
|
+
|
|
49
|
+
# DMARC record
|
|
50
|
+
dig TXT _dmarc.example.com +short
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Expected output:** Each command should return your configured record. No output = record missing.
|
|
54
|
+
|
|
55
|
+
## Sender Reputation
|
|
56
|
+
|
|
57
|
+
### IP Warming
|
|
58
|
+
|
|
59
|
+
New IP/domain? Gradually increase volume:
|
|
60
|
+
|
|
61
|
+
| Week | Daily Volume |
|
|
62
|
+
|------|-------------|
|
|
63
|
+
| 1 | 50-100 |
|
|
64
|
+
| 2 | 200-500 |
|
|
65
|
+
| 3 | 1,000-2,000 |
|
|
66
|
+
| 4 | 5,000-10,000 |
|
|
67
|
+
|
|
68
|
+
Start with engaged users. Send consistently. Don't rush.
|
|
69
|
+
|
|
70
|
+
Learn more: https://resend.com/docs/knowledge-base/warming-up
|
|
71
|
+
|
|
72
|
+
### Maintaining Reputation
|
|
73
|
+
|
|
74
|
+
**Do:** Send to engaged users, keep bounce <4%, complaints <0.1%, remove inactive subscribers.
|
|
75
|
+
|
|
76
|
+
**Don't:** Send to purchased lists, ignore bounces/complaints, send inconsistent volumes
|
|
77
|
+
|
|
78
|
+
## Bounce Handling
|
|
79
|
+
|
|
80
|
+
| Type | Cause | Action |
|
|
81
|
+
|------|-------|--------|
|
|
82
|
+
| Hard bounce | Permanent failure to deliver | Remove immediately |
|
|
83
|
+
| Soft bounce | Transient failure to deliver | Retry: 1h → 4h → 24h, remove after 3-5 failures |
|
|
84
|
+
|
|
85
|
+
**Targets:** <1% good, 1-3% acceptable, 3-4% concerning, >4% critical
|
|
86
|
+
|
|
87
|
+
## Complaint Handling
|
|
88
|
+
|
|
89
|
+
**Targets:** <0.01% excellent, 0.01-0.05% good, >0.05% critical
|
|
90
|
+
|
|
91
|
+
**Reduce complaints:**
|
|
92
|
+
- Only send to opted-in users
|
|
93
|
+
- Make unsubscribe easy and immediate
|
|
94
|
+
- Use clear sender names and "From" addresses
|
|
95
|
+
|
|
96
|
+
**Feedback loops:** Set up with Gmail (Postmaster Tools), Yahoo, Microsoft SNDS. Remove complainers immediately.
|
|
97
|
+
|
|
98
|
+
## Infrastructure
|
|
99
|
+
|
|
100
|
+
**Dedicated sending domain:** Use different subdomains for different sending purposes (e.g., `t.example.com` for transactional emails and `m.example.com` for marketing emails).
|
|
101
|
+
|
|
102
|
+
**DNS TTL:** Low (300s) during setup, high (3600s+) after stable.
|
|
103
|
+
|
|
104
|
+
## Troubleshooting
|
|
105
|
+
|
|
106
|
+
**Emails going to spam?** Check in order:
|
|
107
|
+
1. Authentication (SPF, DKIM, DMARC)
|
|
108
|
+
2. List-Unsubscribe header — required by Gmail/Yahoo since Feb 2024 (see [Compliance](./compliance.md))
|
|
109
|
+
3. Sender reputation (blacklists, complaint rates)
|
|
110
|
+
4. Content
|
|
111
|
+
5. Sending patterns (sudden volume spikes)
|
|
112
|
+
|
|
113
|
+
**Diagnostic tools:**
|
|
114
|
+
- [Google Postmaster Tools](https://postmaster.google.com) - Domain reputation and spam rates
|
|
115
|
+
- [mail-tester.com](https://www.mail-tester.com) - Send a test email, get deliverability score
|
|
116
|
+
- [MXToolbox](https://mxtoolbox.com/blacklists.aspx) - Check blacklist status
|
|
117
|
+
|
|
118
|
+
## Related
|
|
119
|
+
|
|
120
|
+
- [List Management](./list-management.md) - Handle bounces and complaints to protect reputation
|
|
121
|
+
- [Sending Reliability](./sending-reliability.md) - Retry logic and error handling
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Email Capture Best Practices
|
|
2
|
+
|
|
3
|
+
Collecting email addresses responsibly with validation, verification, and proper consent.
|
|
4
|
+
|
|
5
|
+
## Email Validation
|
|
6
|
+
|
|
7
|
+
### Client-Side
|
|
8
|
+
|
|
9
|
+
**HTML5:**
|
|
10
|
+
```html
|
|
11
|
+
<input type="email" required>
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
**Best practices:**
|
|
15
|
+
- Validate on blur or with short debounce
|
|
16
|
+
- Show clear error messages
|
|
17
|
+
- Don't be too strict (allow unusual but valid formats)
|
|
18
|
+
- Client-side validation ≠ deliverability
|
|
19
|
+
|
|
20
|
+
### Server-Side (Recommended)
|
|
21
|
+
|
|
22
|
+
Always validate server-side—client-side can be bypassed.
|
|
23
|
+
|
|
24
|
+
**Check:**
|
|
25
|
+
- Email format (RFC 5322)
|
|
26
|
+
- Domain exists (DNS lookup)
|
|
27
|
+
- Domain has MX records
|
|
28
|
+
- Optionally: disposable email detection
|
|
29
|
+
|
|
30
|
+
Recommended tools: https://resend.com/blog/best-email-verification-apis
|
|
31
|
+
|
|
32
|
+
## Double opt-in
|
|
33
|
+
|
|
34
|
+
Confirms address belongs to user and is deliverable.
|
|
35
|
+
|
|
36
|
+
### Process
|
|
37
|
+
|
|
38
|
+
1. User submits email
|
|
39
|
+
2. Send verification email with unique link/token
|
|
40
|
+
3. User clicks link
|
|
41
|
+
4. Mark as verified
|
|
42
|
+
5. Allow access/add to list
|
|
43
|
+
|
|
44
|
+
**Timing:** Send immediately, include expiration (24-48 hours), allow resend after 60 seconds, limit resend attempts (3/hour).
|
|
45
|
+
|
|
46
|
+
### Single vs Double Opt-In
|
|
47
|
+
|
|
48
|
+
| | Single Opt-In | Double Opt-In |
|
|
49
|
+
|--|---------------|---------------|
|
|
50
|
+
| **Process** | Add to list immediately | Require email confirmation first |
|
|
51
|
+
| **Pros** | Lower friction, faster growth | Verified addresses, better engagement, meets GDPR/CASL |
|
|
52
|
+
| **Cons** | Higher invalid rate, lower engagement | Some users don't confirm |
|
|
53
|
+
| **Use for** | Account creation, transactional | Marketing lists, newsletters |
|
|
54
|
+
|
|
55
|
+
**Recommendation:** Double opt-in for all marketing emails.
|
|
56
|
+
|
|
57
|
+
## Form Design
|
|
58
|
+
|
|
59
|
+
### Email Input
|
|
60
|
+
|
|
61
|
+
- Use `type="email"` for mobile keyboard
|
|
62
|
+
- Include placeholder ("you@example.com")
|
|
63
|
+
- Clear error messages ("Please enter a valid email address" not "Invalid")
|
|
64
|
+
|
|
65
|
+
### Consent Checkboxes (Marketing)
|
|
66
|
+
|
|
67
|
+
- **Unchecked by default** (required)
|
|
68
|
+
- Specific language about what they're signing up for
|
|
69
|
+
- Separate checkboxes for different email types
|
|
70
|
+
- Link to privacy policy
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
☐ Subscribe to our weekly newsletter with product updates
|
|
74
|
+
☐ Send me promotional offers and deals
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Don't:** Pre-check boxes, use vague language, hide in terms.
|
|
78
|
+
|
|
79
|
+
### Form Layout
|
|
80
|
+
|
|
81
|
+
- Keep simple and focused
|
|
82
|
+
- One primary action
|
|
83
|
+
- Clear value proposition
|
|
84
|
+
- Mobile-friendly
|
|
85
|
+
- Accessible (labels, ARIA)
|
|
86
|
+
|
|
87
|
+
## Error Handling
|
|
88
|
+
|
|
89
|
+
### Invalid Email
|
|
90
|
+
|
|
91
|
+
- Show clear error message
|
|
92
|
+
- Suggest corrections for common typos (@gmial.com → @gmail.com)
|
|
93
|
+
- Allow user to fix and resubmit
|
|
94
|
+
|
|
95
|
+
### Already Registered
|
|
96
|
+
|
|
97
|
+
- Accounts: "This email is already registered. [Sign in]"
|
|
98
|
+
- Marketing: "You're already subscribed! [Manage preferences]"
|
|
99
|
+
- Don't reveal if account exists (security)
|
|
100
|
+
|
|
101
|
+
### Rate Limiting
|
|
102
|
+
|
|
103
|
+
- Limit verification emails (3/hour per email)
|
|
104
|
+
- Rate limit form submissions
|
|
105
|
+
- Use CAPTCHA sparingly if needed
|
|
106
|
+
- Monitor for abuse patterns
|
|
107
|
+
|
|
108
|
+
## Verification Emails
|
|
109
|
+
|
|
110
|
+
**Content:**
|
|
111
|
+
- Clear purpose ("Verify your email address")
|
|
112
|
+
- Prominent verification button
|
|
113
|
+
- Expiration time
|
|
114
|
+
- Resend option
|
|
115
|
+
- "I didn't request this" notice
|
|
116
|
+
- Don't include OTP/2FA codes in subject line or preview text as it discourages opens
|
|
117
|
+
|
|
118
|
+
**Design:**
|
|
119
|
+
- Mobile-friendly
|
|
120
|
+
- Large, tappable button
|
|
121
|
+
- Clear call-to-action
|
|
122
|
+
|
|
123
|
+
See [Transactional Emails](./transactional-emails.md) for detailed email design guidance.
|
|
124
|
+
|
|
125
|
+
## Related
|
|
126
|
+
|
|
127
|
+
- [Compliance](./compliance.md) - Legal requirements for consent (GDPR, CASL)
|
|
128
|
+
- [Marketing Emails](./marketing-emails.md) - What happens after capture
|
|
129
|
+
- [Deliverability](./deliverability.md) - How validation improves sender reputation
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Email Types: Transactional vs Marketing
|
|
2
|
+
|
|
3
|
+
Understanding the difference between transactional and marketing emails is crucial for compliance, deliverability, and user experience. This guide explains the distinctions and provides a catalog of transactional emails your app should include.
|
|
4
|
+
|
|
5
|
+
## When to Use This
|
|
6
|
+
|
|
7
|
+
- Deciding whether an email should be transactional or marketing
|
|
8
|
+
- Understanding legal distinctions between email types
|
|
9
|
+
- Planning what transactional emails your app needs
|
|
10
|
+
- Ensuring compliance with email regulations
|
|
11
|
+
- Setting up separate sending infrastructure
|
|
12
|
+
|
|
13
|
+
## Transactional vs Marketing: Key Differences
|
|
14
|
+
|
|
15
|
+
### Transactional Emails
|
|
16
|
+
|
|
17
|
+
**Definition:** Emails that facilitate or confirm a transaction the user initiated or expects. They're directly related to an action the user took or are legal notices you're required to serve.
|
|
18
|
+
|
|
19
|
+
**Characteristics:**
|
|
20
|
+
- User-initiated or expected
|
|
21
|
+
- Time-sensitive and actionable
|
|
22
|
+
- Required for the user to complete an action
|
|
23
|
+
- Does not include promotional material or offers
|
|
24
|
+
- Can be sent without explicit opt-in (with limitations)
|
|
25
|
+
|
|
26
|
+
**Examples:**
|
|
27
|
+
- Password reset links
|
|
28
|
+
- Order confirmations
|
|
29
|
+
- Account verification
|
|
30
|
+
- OTP/2FA codes
|
|
31
|
+
- Shipping notifications
|
|
32
|
+
|
|
33
|
+
**Analogy:**
|
|
34
|
+
Think of transactional emails for everything that would leave you with a paper receipt in the real world: invoices, parking ticket, booking confirmation, etc.
|
|
35
|
+
|
|
36
|
+
### Marketing Emails
|
|
37
|
+
|
|
38
|
+
**Definition:** Emails sent for promotional, advertising, or informational purposes that are not directly related to a specific transaction or legal requirement.
|
|
39
|
+
|
|
40
|
+
**Characteristics:**
|
|
41
|
+
- Promotional or informational content
|
|
42
|
+
- Not time-sensitive to complete a transaction
|
|
43
|
+
- Require explicit opt-in (consent)
|
|
44
|
+
- Must include unsubscribe options
|
|
45
|
+
- Subject to stricter compliance requirements
|
|
46
|
+
|
|
47
|
+
**Examples:**
|
|
48
|
+
- Newsletters
|
|
49
|
+
- Abandoned cart
|
|
50
|
+
- Product announcements
|
|
51
|
+
- Promotional offers
|
|
52
|
+
- Company updates
|
|
53
|
+
- Educational content
|
|
54
|
+
|
|
55
|
+
## Legal Distinctions
|
|
56
|
+
|
|
57
|
+
### CAN-SPAM Act (US)
|
|
58
|
+
|
|
59
|
+
**Transactional emails:**
|
|
60
|
+
- Can be sent without opt-in
|
|
61
|
+
- Must be related to a transaction
|
|
62
|
+
- Cannot contain promotional content (with exceptions)
|
|
63
|
+
- Must identify sender and provide contact information
|
|
64
|
+
|
|
65
|
+
**Marketing emails:**
|
|
66
|
+
- Require opt-out mechanism (not opt-in in US)
|
|
67
|
+
- Must include clear sender identification
|
|
68
|
+
- Must include physical mailing address
|
|
69
|
+
- Must honor opt-out requests within 10 business days
|
|
70
|
+
|
|
71
|
+
### GDPR (EU)
|
|
72
|
+
|
|
73
|
+
**Transactional emails:**
|
|
74
|
+
- Can be sent based on legitimate interest or contract fulfillment
|
|
75
|
+
- Must be necessary for service delivery
|
|
76
|
+
- Cannot contain marketing content without consent
|
|
77
|
+
|
|
78
|
+
**Marketing emails:**
|
|
79
|
+
- Require explicit opt-in consent
|
|
80
|
+
- Must clearly state purpose of data collection
|
|
81
|
+
- Must provide easy unsubscribe
|
|
82
|
+
- Subject to data protection requirements
|
|
83
|
+
|
|
84
|
+
### CASL (Canada)
|
|
85
|
+
|
|
86
|
+
**Transactional emails:**
|
|
87
|
+
- Can be sent without consent if related to ongoing business relationship
|
|
88
|
+
- Must be factual and not promotional
|
|
89
|
+
|
|
90
|
+
**Marketing emails:**
|
|
91
|
+
- Require express or implied consent
|
|
92
|
+
- Must include unsubscribe mechanism
|
|
93
|
+
- Must identify sender clearly
|
|
94
|
+
|
|
95
|
+
## When to Use Each Type
|
|
96
|
+
|
|
97
|
+
### Use Transactional When:
|
|
98
|
+
|
|
99
|
+
- User needs the email to complete an action
|
|
100
|
+
- Email confirms a transaction or account change
|
|
101
|
+
- Email provides security-related information
|
|
102
|
+
- Email is expected based on user action
|
|
103
|
+
- Content is time-sensitive and actionable
|
|
104
|
+
- You're required to serve a notification for compliance
|
|
105
|
+
|
|
106
|
+
### Use Marketing When:
|
|
107
|
+
|
|
108
|
+
- Promoting products or services
|
|
109
|
+
- Sending newsletters or updates
|
|
110
|
+
- Sharing educational content
|
|
111
|
+
- Announcing features or company news
|
|
112
|
+
- Content is not required for a transaction
|
|
113
|
+
|
|
114
|
+
## Hybrid Emails: The Gray Area
|
|
115
|
+
|
|
116
|
+
Some emails mix transactional and marketing content. This isn't best practice and should be avoided.
|
|
117
|
+
|
|
118
|
+
**Best practice:** Keep transactional and marketing separate.
|
|
119
|
+
|
|
120
|
+
**Example of problematic hybrid:**
|
|
121
|
+
- Newsletter (marketing) with a small order status update (transactional)
|
|
122
|
+
|
|
123
|
+
## Transactional Email Catalog
|
|
124
|
+
|
|
125
|
+
For a complete catalog of transactional emails and recommended combinations by app type, see [Transactional Email Catalog](./transactional-email-catalog.md).
|
|
126
|
+
|
|
127
|
+
**Quick reference - Essential emails for most apps:**
|
|
128
|
+
1. **Email verification** - Required for account creation
|
|
129
|
+
2. **Password reset** - Required for account recovery
|
|
130
|
+
3. **Welcome email** - Good user experience
|
|
131
|
+
|
|
132
|
+
The catalog includes detailed guidance for:
|
|
133
|
+
- Authentication-focused apps
|
|
134
|
+
- Newsletter / content platforms
|
|
135
|
+
- E-commerce / marketplaces
|
|
136
|
+
- SaaS / subscription services
|
|
137
|
+
- Financial / fintech apps
|
|
138
|
+
- Social / community platforms
|
|
139
|
+
- Developer tools / API platforms
|
|
140
|
+
- Healthcare / HIPAA-compliant apps
|
|
141
|
+
|
|
142
|
+
## Sending Infrastructure
|
|
143
|
+
|
|
144
|
+
### Separate subdomains
|
|
145
|
+
|
|
146
|
+
**Best practice:** Use separate sending subdomains for transactional and marketing emails.
|
|
147
|
+
|
|
148
|
+
**Benefits:**
|
|
149
|
+
- Protect transactional deliverability
|
|
150
|
+
- Different authentication domains
|
|
151
|
+
- Independent reputation
|
|
152
|
+
- Easier compliance management
|
|
153
|
+
|
|
154
|
+
**Implementation:**
|
|
155
|
+
- Use different subdomains (e.g., `t.example.com` for transactional, `m.example.com` for marketing)
|
|
156
|
+
|
|
157
|
+
### Email Service Considerations
|
|
158
|
+
|
|
159
|
+
Choose an email service that:
|
|
160
|
+
- Provides reliable delivery for transactional emails
|
|
161
|
+
- Offers separate sending domains
|
|
162
|
+
- Has good API for programmatic sending
|
|
163
|
+
- Provides webhooks for delivery events
|
|
164
|
+
- Supports authentication setup (SPF, DKIM, DMARC)
|
|
165
|
+
|
|
166
|
+
Services like Resend are designed for transactional emails and provide the infrastructure and tools needed for reliable delivery. They also offer powerful marketing features.
|
|
167
|
+
|
|
168
|
+
## Related Topics
|
|
169
|
+
|
|
170
|
+
- [Transactional Emails](./transactional-emails.md) - Best practices for sending transactional emails
|
|
171
|
+
- [Marketing Emails](./marketing-emails.md) - Best practices for marketing emails
|
|
172
|
+
- [Compliance](./compliance.md) - Legal requirements for each email type
|
|
173
|
+
- [Deliverability](./deliverability.md) - Ensuring transactional emails are delivered
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# List Management
|
|
2
|
+
|
|
3
|
+
Maintaining clean email lists through suppression, hygiene, and data retention.
|
|
4
|
+
|
|
5
|
+
## Suppression Lists
|
|
6
|
+
|
|
7
|
+
A suppression list prevents sending to addresses that should never receive email.
|
|
8
|
+
|
|
9
|
+
### What to Suppress
|
|
10
|
+
|
|
11
|
+
| Reason | Action | Can Unsuppress? |
|
|
12
|
+
|--------|--------|-----------------|
|
|
13
|
+
| Hard bounce | Add immediately | No (address invalid) |
|
|
14
|
+
| Complaint (spam) | Add immediately | No (legal requirement) |
|
|
15
|
+
| Soft bounce (3x) | Add after threshold | Yes, after 30-90 days |
|
|
16
|
+
| Manual removal | Add on request | Only if user requests |
|
|
17
|
+
|
|
18
|
+
### Implementation
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// Suppression list schema
|
|
22
|
+
interface SuppressionEntry {
|
|
23
|
+
email: string;
|
|
24
|
+
reason: 'hard_bounce' | 'complaint' | 'unsubscribe' | 'soft_bounce' | 'manual';
|
|
25
|
+
created_at: Date;
|
|
26
|
+
source_email_id?: string; // Which email triggered this
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Check before every send
|
|
30
|
+
async function canSendTo(email: string): Promise<boolean> {
|
|
31
|
+
const suppressed = await db.suppressions.findOne({ email });
|
|
32
|
+
return !suppressed;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Add to suppression list
|
|
36
|
+
async function suppressEmail(email: string, reason: string, sourceId?: string) {
|
|
37
|
+
await db.suppressions.upsert({
|
|
38
|
+
email: email.toLowerCase(),
|
|
39
|
+
reason,
|
|
40
|
+
created_at: new Date(),
|
|
41
|
+
source_email_id: sourceId,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Pre-Send Check
|
|
47
|
+
|
|
48
|
+
**Always check suppression before sending:**
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
async function sendEmail(to: string, emailData: EmailData) {
|
|
52
|
+
if (!await canSendTo(to)) {
|
|
53
|
+
console.log(`Skipping suppressed email: ${to}`);
|
|
54
|
+
return { skipped: true, reason: 'suppressed' };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return await resend.emails.send({ to, ...emailData });
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## List Hygiene
|
|
62
|
+
|
|
63
|
+
Regular maintenance to keep lists healthy.
|
|
64
|
+
|
|
65
|
+
### Automated Cleanup
|
|
66
|
+
|
|
67
|
+
| Task | Frequency | Action |
|
|
68
|
+
|------|-----------|--------|
|
|
69
|
+
| Remove hard bounces | Real-time (via webhook) | Immediate suppression |
|
|
70
|
+
| Remove complaints | Real-time (via webhook) | Immediate suppression |
|
|
71
|
+
| Process unsubscribes | Real-time | Remove from marketing lists |
|
|
72
|
+
| Review soft bounces | Daily | Suppress after 3 failures |
|
|
73
|
+
| Remove inactive | Monthly | Re-engagement → remove |
|
|
74
|
+
|
|
75
|
+
Learn more: https://resend.com/docs/knowledge-base/audience-hygiene
|
|
76
|
+
|
|
77
|
+
### Re-engagement Campaigns
|
|
78
|
+
|
|
79
|
+
Before removing inactive subscribers:
|
|
80
|
+
|
|
81
|
+
1. **Identify inactive:** No opens/clicks in 45-90 days
|
|
82
|
+
2. **Send re-engagement:** "We miss you" or "Still interested?"
|
|
83
|
+
3. **Wait 14-30 days** for response
|
|
84
|
+
4. **Remove non-responders** from active lists
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
async function runReengagement() {
|
|
88
|
+
const inactive = await getInactiveSubscribers(90); // 90 days
|
|
89
|
+
|
|
90
|
+
for (const subscriber of inactive) {
|
|
91
|
+
if (!subscriber.reengagement_sent) {
|
|
92
|
+
await sendReengagementEmail(subscriber);
|
|
93
|
+
await markReengagementSent(subscriber.email);
|
|
94
|
+
} else if (daysSince(subscriber.reengagement_sent) > 30) {
|
|
95
|
+
await removeFromMarketingLists(subscriber.email);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Data Retention
|
|
102
|
+
|
|
103
|
+
### Email Logs
|
|
104
|
+
|
|
105
|
+
| Data Type | Recommended Retention | Notes |
|
|
106
|
+
|-----------|----------------------|-------|
|
|
107
|
+
| Send attempts | 90 days | Debugging, analytics |
|
|
108
|
+
| Delivery status | 90 days | Compliance, reporting |
|
|
109
|
+
| Bounce/complaint events | 3 years | Required for CASL |
|
|
110
|
+
| Suppression list | Indefinite | Never delete |
|
|
111
|
+
| Email content | 30 days | Storage costs |
|
|
112
|
+
| Consent records | 3 years after expiry | Legal requirement |
|
|
113
|
+
|
|
114
|
+
### Retention Policy Implementation
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
// Daily cleanup job
|
|
118
|
+
async function cleanupOldData() {
|
|
119
|
+
const now = new Date();
|
|
120
|
+
|
|
121
|
+
// Delete old email logs (keep 90 days)
|
|
122
|
+
await db.emailLogs.deleteMany({
|
|
123
|
+
created_at: { $lt: subDays(now, 90) }
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// Delete old email content (keep 30 days)
|
|
127
|
+
await db.emailContent.deleteMany({
|
|
128
|
+
created_at: { $lt: subDays(now, 30) }
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Never delete: suppressions, consent records
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Metrics to Monitor
|
|
136
|
+
|
|
137
|
+
| Metric | Target | Alert Threshold |
|
|
138
|
+
|--------|--------|-----------------|
|
|
139
|
+
| Bounce rate | <2% | >2% |
|
|
140
|
+
| Complaint rate | <0.05% | >0.05% |
|
|
141
|
+
| Suppression list growth | Stable | Sudden spike |
|
|
142
|
+
|
|
143
|
+
## Transactional vs Marketing Lists
|
|
144
|
+
|
|
145
|
+
**Keep separate:**
|
|
146
|
+
- Transactional: Can send to anyone with account relationship
|
|
147
|
+
- Marketing: Only opted-in subscribers
|
|
148
|
+
|
|
149
|
+
**Suppression applies to both:** Hard bounces and complaints suppress across all email types.
|
|
150
|
+
|
|
151
|
+
**Unsubscribe is marketing-only:** User unsubscribing from marketing can still receive transactional emails (password resets, order confirmations).
|
|
152
|
+
|
|
153
|
+
## Related
|
|
154
|
+
|
|
155
|
+
- [Webhooks & Events](./webhooks-events.md) - Receive bounce/complaint notifications
|
|
156
|
+
- [Deliverability](./deliverability.md) - How list hygiene affects sender reputation
|
|
157
|
+
- [Compliance](./compliance.md) - Legal requirements for data retention
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Marketing Email Best Practices
|
|
2
|
+
|
|
3
|
+
Promotional emails that require explicit consent and provide value to recipients.
|
|
4
|
+
|
|
5
|
+
## Core Principles
|
|
6
|
+
|
|
7
|
+
1. **Consent first** - Explicit opt-in required (especially GDPR/CASL)
|
|
8
|
+
2. **Value-driven** - Provide useful content, not just promotions
|
|
9
|
+
3. **Respect preferences** - Let users control frequency and content types
|
|
10
|
+
|
|
11
|
+
## Opt-In Requirements
|
|
12
|
+
|
|
13
|
+
### Explicit Opt-In
|
|
14
|
+
|
|
15
|
+
**What counts:**
|
|
16
|
+
- User checks unchecked box
|
|
17
|
+
- User clicks "Subscribe" button
|
|
18
|
+
- User completes form with clear subscription intent
|
|
19
|
+
|
|
20
|
+
**What doesn't count:**
|
|
21
|
+
- Pre-checked boxes
|
|
22
|
+
- Opt-out model
|
|
23
|
+
- Assumed consent from purchase
|
|
24
|
+
- Purchased/rented lists
|
|
25
|
+
|
|
26
|
+
### Informed Consent
|
|
27
|
+
|
|
28
|
+
Disclose: email types, frequency, sender identity, how to unsubscribe.
|
|
29
|
+
|
|
30
|
+
✅ "Subscribe to our weekly newsletter with product updates and tips"
|
|
31
|
+
❌ "Sign up for emails"
|
|
32
|
+
|
|
33
|
+
### Double Opt-In (Recommended)
|
|
34
|
+
|
|
35
|
+
1. User submits email
|
|
36
|
+
2. Send confirmation email with verification link
|
|
37
|
+
3. User clicks to confirm
|
|
38
|
+
4. Add to list only after confirmation
|
|
39
|
+
|
|
40
|
+
Benefits: Verifies deliverability, confirms intent, reduces complaints, required in some regions (Germany).
|
|
41
|
+
|
|
42
|
+
## Unsubscribe Requirements
|
|
43
|
+
|
|
44
|
+
**Must be:**
|
|
45
|
+
- Prominent in every email
|
|
46
|
+
- One-click (preferred)
|
|
47
|
+
- Immediate (GDPR) or within 10 days (CAN-SPAM) (immediate preferred)
|
|
48
|
+
- Free, no login required
|
|
49
|
+
|
|
50
|
+
**Preference center options:** Frequency (daily/weekly/monthly), content types, complete unsubscribe.
|
|
51
|
+
|
|
52
|
+
## Content and Design
|
|
53
|
+
|
|
54
|
+
### Subject Lines
|
|
55
|
+
|
|
56
|
+
- Clear and specific (50 chars or less for mobile)
|
|
57
|
+
- Create curiosity without misleading
|
|
58
|
+
- A/B test regularly
|
|
59
|
+
|
|
60
|
+
✅ "Your weekly digest: 5 productivity tips"
|
|
61
|
+
❌ "You won't believe what happened!"
|
|
62
|
+
|
|
63
|
+
### Structure
|
|
64
|
+
|
|
65
|
+
**Above fold:** Value proposition, primary CTA, engaging visual
|
|
66
|
+
|
|
67
|
+
**Body:** Scannable (short paragraphs, bullets), clear hierarchy, multiple CTAs
|
|
68
|
+
|
|
69
|
+
**Footer:** Unsubscribe link, company info, physical address (CAN-SPAM), social links
|
|
70
|
+
|
|
71
|
+
### Mobile-First
|
|
72
|
+
|
|
73
|
+
- Single column layout
|
|
74
|
+
- 44x44px minimum buttons
|
|
75
|
+
- 16px minimum text
|
|
76
|
+
- Test on iOS, Android, dark mode
|
|
77
|
+
|
|
78
|
+
## Segmentation
|
|
79
|
+
|
|
80
|
+
**Segment by:** Behavior (purchases, activity), demographics, preferences, engagement level, signup source.
|
|
81
|
+
|
|
82
|
+
Benefits: Higher open/click rates, lower unsubscribes, better experience.
|
|
83
|
+
|
|
84
|
+
## Personalization
|
|
85
|
+
|
|
86
|
+
**Options:** Name in subject/greeting, location-specific content, behavior-based recommendations, purchase history.
|
|
87
|
+
|
|
88
|
+
**Don't over-personalize** - can feel intrusive. Use data you have permission to use.
|
|
89
|
+
|
|
90
|
+
## Frequency and Timing
|
|
91
|
+
|
|
92
|
+
**Frequency:** Start conservative, increase based on engagement, let users set preferences, monitor unsubscribe rates.
|
|
93
|
+
|
|
94
|
+
**Timing:** Weekday mornings (9-11 AM local), Tuesday-Thursday often best. Test your specific audience.
|
|
95
|
+
|
|
96
|
+
## List Hygiene
|
|
97
|
+
|
|
98
|
+
**Remove immediately:** Hard bounces, unsubscribes, complaints
|
|
99
|
+
|
|
100
|
+
**Remove after inactivity:** Send re-engagement campaign first, then remove non-responders
|
|
101
|
+
|
|
102
|
+
**Monitor:** Bounce rate <2%, complaint rate <0.05%
|
|
103
|
+
|
|
104
|
+
## Required Elements (All Marketing Emails)
|
|
105
|
+
|
|
106
|
+
- Clear sender identification
|
|
107
|
+
- Physical mailing address (CAN-SPAM)
|
|
108
|
+
- Unsubscribe mechanism
|
|
109
|
+
- Indication it's marketing (GDPR)
|
|
110
|
+
|
|
111
|
+
## Related
|
|
112
|
+
|
|
113
|
+
- [Compliance](./compliance.md) - Detailed legal requirements by region
|
|
114
|
+
- [Email Capture](./email-capture.md) - Collecting consent properly
|
|
115
|
+
- [List Management](./list-management.md) - Maintaining list hygiene
|