@friedbotstudio/create-baseline 0.1.0 → 0.2.1
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 +5 -0
- package/bin/cli.js +8 -2
- package/obj/template/.claude/skills/audit-baseline/audit.sh +11 -5
- package/obj/template/.claude/skills/google-analytics/SKILL.md +129 -0
- package/obj/template/.claude/skills/google-analytics/references/audiences.md +389 -0
- package/obj/template/.claude/skills/google-analytics/references/bigquery.md +470 -0
- package/obj/template/.claude/skills/google-analytics/references/custom-dimensions.md +355 -0
- package/obj/template/.claude/skills/google-analytics/references/custom-events.md +383 -0
- package/obj/template/.claude/skills/google-analytics/references/data-management.md +416 -0
- package/obj/template/.claude/skills/google-analytics/references/debugview.md +364 -0
- package/obj/template/.claude/skills/google-analytics/references/events-fundamentals.md +398 -0
- package/obj/template/.claude/skills/google-analytics/references/gtag.md +502 -0
- package/obj/template/.claude/skills/google-analytics/references/gtm-integration.md +483 -0
- package/obj/template/.claude/skills/google-analytics/references/measurement-protocol.md +519 -0
- package/obj/template/.claude/skills/google-analytics/references/privacy.md +441 -0
- package/obj/template/.claude/skills/google-analytics/references/recommended-events.md +464 -0
- package/obj/template/.claude/skills/google-analytics/references/reporting.md +397 -0
- package/obj/template/.claude/skills/google-analytics/references/setup.md +344 -0
- package/obj/template/.claude/skills/google-analytics/references/user-tracking.md +417 -0
- package/obj/template/.claude/skills/optimize-seo/SKILL.md +313 -0
- package/obj/template/.claude/skills/optimize-seo/scripts/pagespeed.mjs +197 -0
- package/obj/template/.claude/skills/pagespeed-insights/LICENSE.md +37 -0
- package/obj/template/.claude/skills/pagespeed-insights/SKILL.md +446 -0
- package/obj/template/.claude/skills/pagespeed-insights/reference.md +50 -0
- package/obj/template/CLAUDE.md +3 -3
- package/obj/template/docs/init/seed.md +2 -2
- package/obj/template/manifest.json +27 -6
- package/package.json +7 -2
- package/src/CLAUDE.template.md +3 -3
- package/src/cli/install.js +14 -4
- package/src/seed.template.md +2 -2
- package/obj/template/.claude/hooks/lib/__pycache__/resume_writer.cpython-314.pyc +0 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
# GA4 Custom Events
|
|
2
|
+
|
|
3
|
+
Expert guidance for creating business-specific custom events beyond Google's recommended events.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Custom events enable measurement of unique business goals, industry-specific actions, and contextual behaviours not covered by Google's recommended events. This reference covers event naming conventions, parameter design strategies, and implementation across all platforms.
|
|
8
|
+
|
|
9
|
+
## When to Use Custom Events
|
|
10
|
+
|
|
11
|
+
Create custom events when:
|
|
12
|
+
|
|
13
|
+
- Business action not covered by recommended events
|
|
14
|
+
- Industry-specific tracking requirements
|
|
15
|
+
- Unique user interactions to measure
|
|
16
|
+
- Business-specific conversion points
|
|
17
|
+
- Detailed behavioural analysis needs
|
|
18
|
+
|
|
19
|
+
## Event Naming Conventions
|
|
20
|
+
|
|
21
|
+
### Format and Constraints
|
|
22
|
+
|
|
23
|
+
| Constraint | Value |
|
|
24
|
+
|------------|-------|
|
|
25
|
+
| Case | snake_case (lowercase with underscores) |
|
|
26
|
+
| Maximum length | 40 characters |
|
|
27
|
+
| Starting character | Letter |
|
|
28
|
+
| Allowed characters | Letters, numbers, underscores |
|
|
29
|
+
|
|
30
|
+
### Naming Framework
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
[action]_[object]_[context]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Examples:**
|
|
37
|
+
- product_comparison_viewed
|
|
38
|
+
- pricing_calculator_used
|
|
39
|
+
- whitepaper_downloaded
|
|
40
|
+
- trial_signup_completed
|
|
41
|
+
- support_ticket_created
|
|
42
|
+
|
|
43
|
+
### Good Event Names
|
|
44
|
+
|
|
45
|
+
| Event Name | Description |
|
|
46
|
+
|------------|-------------|
|
|
47
|
+
| demo_requested | User requested product demo |
|
|
48
|
+
| feature_trial_started | User started feature trial |
|
|
49
|
+
| integration_configured | User set up integration |
|
|
50
|
+
| report_exported | User exported report |
|
|
51
|
+
| team_member_invited | User invited team member |
|
|
52
|
+
|
|
53
|
+
### Anti-Patterns (Avoid)
|
|
54
|
+
|
|
55
|
+
| Bad Name | Problem | Better Name |
|
|
56
|
+
|----------|---------|-------------|
|
|
57
|
+
| click | Too generic | button_click |
|
|
58
|
+
| event1 | Not descriptive | form_submit |
|
|
59
|
+
| MyEvent | Wrong case | my_event |
|
|
60
|
+
| trackAction | Camel case | track_action |
|
|
61
|
+
| data | Meaningless | data_exported |
|
|
62
|
+
|
|
63
|
+
## Event Parameter Design
|
|
64
|
+
|
|
65
|
+
### Parameter Strategy
|
|
66
|
+
|
|
67
|
+
For each custom event, identify:
|
|
68
|
+
|
|
69
|
+
1. **What is the action?** The user behaviour being measured
|
|
70
|
+
2. **What context is needed?** Information to analyse the action
|
|
71
|
+
3. **What parameters provide context?** Data points to collect
|
|
72
|
+
4. **What are the constraints?** Length limits, data types
|
|
73
|
+
|
|
74
|
+
### Parameter Limits
|
|
75
|
+
|
|
76
|
+
| Limit | Value |
|
|
77
|
+
|-------|-------|
|
|
78
|
+
| Parameters per event | 25 |
|
|
79
|
+
| Parameter name length | 40 characters |
|
|
80
|
+
| Parameter value length | 100 characters |
|
|
81
|
+
| Data types | String, Integer, Float |
|
|
82
|
+
|
|
83
|
+
### Parameter Examples
|
|
84
|
+
|
|
85
|
+
**demo_requested Event:**
|
|
86
|
+
```javascript
|
|
87
|
+
gtag('event', 'demo_requested', {
|
|
88
|
+
'demo_type': 'product_walkthrough',
|
|
89
|
+
'industry': 'technology',
|
|
90
|
+
'company_size': 'enterprise',
|
|
91
|
+
'lead_source': 'organic_search',
|
|
92
|
+
'product_interest': 'analytics_suite'
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**course_enrollment Event:**
|
|
97
|
+
```javascript
|
|
98
|
+
gtag('event', 'course_enrollment', {
|
|
99
|
+
'course_id': 'COURSE_101',
|
|
100
|
+
'course_name': 'Advanced GA4',
|
|
101
|
+
'instructor': 'Jane Smith',
|
|
102
|
+
'price': 99.99,
|
|
103
|
+
'currency': 'USD',
|
|
104
|
+
'level': 'advanced',
|
|
105
|
+
'duration_hours': 8
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**support_ticket_created Event:**
|
|
110
|
+
```javascript
|
|
111
|
+
gtag('event', 'support_ticket_created', {
|
|
112
|
+
'ticket_type': 'bug_report',
|
|
113
|
+
'product': 'mobile_app',
|
|
114
|
+
'severity': 'high',
|
|
115
|
+
'department': 'engineering',
|
|
116
|
+
'resolution_time_expected': 24
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Industry-Specific Patterns
|
|
121
|
+
|
|
122
|
+
### SaaS Events
|
|
123
|
+
|
|
124
|
+
| Event | Parameters |
|
|
125
|
+
|-------|------------|
|
|
126
|
+
| trial_started | plan_type, trial_duration, feature_count |
|
|
127
|
+
| trial_ended | conversion_status, days_active, features_used |
|
|
128
|
+
| upgrade_initiated | from_plan, to_plan, estimated_value |
|
|
129
|
+
| plan_downgraded | from_plan, to_plan, reason_category |
|
|
130
|
+
| feature_activated | feature_name, activation_method |
|
|
131
|
+
| integration_connected | integration_name, connection_type |
|
|
132
|
+
| api_key_generated | key_purpose, environment |
|
|
133
|
+
| workspace_created | workspace_type, team_size |
|
|
134
|
+
|
|
135
|
+
### Education Events
|
|
136
|
+
|
|
137
|
+
| Event | Parameters |
|
|
138
|
+
|-------|------------|
|
|
139
|
+
| lesson_completed | course_id, lesson_id, completion_time |
|
|
140
|
+
| quiz_submitted | quiz_id, score_percentage, attempts |
|
|
141
|
+
| certificate_earned | course_id, grade, completion_date |
|
|
142
|
+
| course_enrolled | course_id, enrollment_type, price |
|
|
143
|
+
| instructor_contacted | inquiry_type, response_time |
|
|
144
|
+
| resource_downloaded | resource_type, file_format |
|
|
145
|
+
| discussion_posted | topic_category, word_count |
|
|
146
|
+
| peer_review_submitted | assignment_id, rating_given |
|
|
147
|
+
|
|
148
|
+
### Media Events
|
|
149
|
+
|
|
150
|
+
| Event | Parameters |
|
|
151
|
+
|-------|------------|
|
|
152
|
+
| article_shared | article_id, share_platform, category |
|
|
153
|
+
| video_watched | video_id, duration, engagement_percent |
|
|
154
|
+
| podcast_completed | episode_id, listen_duration, completion |
|
|
155
|
+
| newsletter_subscribed | newsletter_type, source |
|
|
156
|
+
| content_bookmarked | content_id, content_type |
|
|
157
|
+
| author_followed | author_id, follow_source |
|
|
158
|
+
| comment_posted | content_id, word_count |
|
|
159
|
+
| paywall_reached | content_type, view_count_prior |
|
|
160
|
+
|
|
161
|
+
### E-commerce (Beyond Recommended)
|
|
162
|
+
|
|
163
|
+
| Event | Parameters |
|
|
164
|
+
|-------|------------|
|
|
165
|
+
| product_compared | products_compared, category |
|
|
166
|
+
| review_submitted | product_id, star_rating, has_photo |
|
|
167
|
+
| wishlist_shared | item_count, share_method |
|
|
168
|
+
| size_guide_viewed | product_category, size_selected |
|
|
169
|
+
| store_locator_used | postcode, results_count |
|
|
170
|
+
| gift_wrap_selected | wrap_type, price |
|
|
171
|
+
| loyalty_redeemed | points_redeemed, reward_type |
|
|
172
|
+
| back_in_stock_signup | product_id, notification_preference |
|
|
173
|
+
|
|
174
|
+
## Implementation Examples
|
|
175
|
+
|
|
176
|
+
### gtag.js Implementation
|
|
177
|
+
|
|
178
|
+
```javascript
|
|
179
|
+
// Simple event
|
|
180
|
+
gtag('event', 'demo_requested', {
|
|
181
|
+
'demo_type': 'product_walkthrough',
|
|
182
|
+
'industry': 'technology'
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// Event with multiple parameters
|
|
186
|
+
gtag('event', 'subscription_changed', {
|
|
187
|
+
'change_type': 'upgrade',
|
|
188
|
+
'from_plan': 'basic',
|
|
189
|
+
'to_plan': 'professional',
|
|
190
|
+
'price_difference': 50,
|
|
191
|
+
'currency': 'USD',
|
|
192
|
+
'billing_cycle': 'monthly'
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### GTM Data Layer Implementation
|
|
197
|
+
|
|
198
|
+
```javascript
|
|
199
|
+
// Push event to data layer
|
|
200
|
+
dataLayer.push({
|
|
201
|
+
'event': 'demo_requested',
|
|
202
|
+
'demo_type': 'product_walkthrough',
|
|
203
|
+
'industry': 'technology',
|
|
204
|
+
'company_size': 'enterprise'
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// In GTM:
|
|
208
|
+
// 1. Create Data Layer Variables for each parameter
|
|
209
|
+
// 2. Create Custom Event trigger for 'demo_requested'
|
|
210
|
+
// 3. Create GA4 Event tag with mapped parameters
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Measurement Protocol (Server-Side)
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
import requests
|
|
217
|
+
import json
|
|
218
|
+
|
|
219
|
+
MEASUREMENT_ID = "G-XXXXXXXXXX"
|
|
220
|
+
API_SECRET = "your_api_secret"
|
|
221
|
+
|
|
222
|
+
def send_custom_event(client_id, event_name, params):
|
|
223
|
+
url = f"https://www.google-analytics.com/mp/collect?measurement_id={MEASUREMENT_ID}&api_secret={API_SECRET}"
|
|
224
|
+
|
|
225
|
+
payload = {
|
|
226
|
+
"client_id": client_id,
|
|
227
|
+
"events": [{
|
|
228
|
+
"name": event_name,
|
|
229
|
+
"params": params
|
|
230
|
+
}]
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
response = requests.post(
|
|
234
|
+
url,
|
|
235
|
+
headers={"Content-Type": "application/json"},
|
|
236
|
+
data=json.dumps(payload)
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
return response.status_code == 204
|
|
240
|
+
|
|
241
|
+
# Example usage
|
|
242
|
+
send_custom_event(
|
|
243
|
+
client_id="123.456",
|
|
244
|
+
event_name="subscription_renewed",
|
|
245
|
+
params={
|
|
246
|
+
"plan_type": "professional",
|
|
247
|
+
"renewal_value": 299.00,
|
|
248
|
+
"currency": "USD",
|
|
249
|
+
"renewal_count": 3
|
|
250
|
+
}
|
|
251
|
+
)
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Registering Custom Dimensions
|
|
255
|
+
|
|
256
|
+
Custom parameters won't appear in GA4 reports until registered as custom dimensions.
|
|
257
|
+
|
|
258
|
+
### Registration Process
|
|
259
|
+
|
|
260
|
+
1. **Send parameter in event** (any platform)
|
|
261
|
+
2. **Verify in DebugView** (Admin -> DebugView)
|
|
262
|
+
3. **Register dimension:**
|
|
263
|
+
- Admin -> Data Display -> Custom Definitions
|
|
264
|
+
- Create Custom Dimension
|
|
265
|
+
- Dimension Name: Human-friendly (e.g., "Demo Type")
|
|
266
|
+
- Scope: Event, User, or Item
|
|
267
|
+
- Event Parameter: Exact name from code (e.g., "demo_type")
|
|
268
|
+
4. **Wait 24-48 hours** for data to populate
|
|
269
|
+
5. **Use in reports** (Explorations, Standard Reports)
|
|
270
|
+
|
|
271
|
+
### Scope Selection
|
|
272
|
+
|
|
273
|
+
| Scope | Use For | Example |
|
|
274
|
+
|-------|---------|---------|
|
|
275
|
+
| Event | Single event data | demo_type, button_name |
|
|
276
|
+
| User | User attributes | subscription_tier, customer_segment |
|
|
277
|
+
| Item | Product data | item_color, item_size |
|
|
278
|
+
|
|
279
|
+
## Testing Custom Events
|
|
280
|
+
|
|
281
|
+
### DebugView Workflow
|
|
282
|
+
|
|
283
|
+
1. Enable debug mode:
|
|
284
|
+
- Chrome extension: Google Analytics Debugger
|
|
285
|
+
- URL parameter: `?debug_mode=true`
|
|
286
|
+
- gtag config: `debug_mode: true`
|
|
287
|
+
|
|
288
|
+
2. Trigger custom event
|
|
289
|
+
|
|
290
|
+
3. Check DebugView:
|
|
291
|
+
- Event appears with correct name
|
|
292
|
+
- All parameters present
|
|
293
|
+
- Parameter values correct
|
|
294
|
+
- No errors or warnings
|
|
295
|
+
|
|
296
|
+
### Validation Checklist
|
|
297
|
+
|
|
298
|
+
- [ ] Event name follows snake_case
|
|
299
|
+
- [ ] Event name under 40 characters
|
|
300
|
+
- [ ] All parameters present
|
|
301
|
+
- [ ] Parameter names under 40 characters
|
|
302
|
+
- [ ] Parameter values under 100 characters
|
|
303
|
+
- [ ] Correct data types (string vs number)
|
|
304
|
+
- [ ] No PII in parameters
|
|
305
|
+
|
|
306
|
+
## Common Issues
|
|
307
|
+
|
|
308
|
+
### Event Not Appearing
|
|
309
|
+
|
|
310
|
+
**Causes:**
|
|
311
|
+
- Debug mode not enabled
|
|
312
|
+
- Wrong Measurement ID
|
|
313
|
+
- JavaScript error before gtag call
|
|
314
|
+
- Ad blocker blocking
|
|
315
|
+
|
|
316
|
+
**Solutions:**
|
|
317
|
+
1. Enable Google Analytics Debugger extension
|
|
318
|
+
2. Verify Measurement ID
|
|
319
|
+
3. Check browser console for errors
|
|
320
|
+
4. Test in incognito mode
|
|
321
|
+
|
|
322
|
+
### Parameters Missing
|
|
323
|
+
|
|
324
|
+
**Causes:**
|
|
325
|
+
- Parameter name typo
|
|
326
|
+
- Value is undefined/null
|
|
327
|
+
- Data layer variable not populated
|
|
328
|
+
|
|
329
|
+
**Solutions:**
|
|
330
|
+
1. Check exact parameter name
|
|
331
|
+
2. Validate value before sending
|
|
332
|
+
3. Debug data layer in GTM Preview
|
|
333
|
+
|
|
334
|
+
### Wrong Data Type
|
|
335
|
+
|
|
336
|
+
**Causes:**
|
|
337
|
+
- Sending string instead of number
|
|
338
|
+
- Array where string expected
|
|
339
|
+
|
|
340
|
+
**Solutions:**
|
|
341
|
+
1. Validate data type before sending
|
|
342
|
+
2. Convert values appropriately
|
|
343
|
+
3. Test with DebugView
|
|
344
|
+
|
|
345
|
+
## Best Practices
|
|
346
|
+
|
|
347
|
+
### Design Guidelines
|
|
348
|
+
|
|
349
|
+
1. **Be consistent** - Same event name everywhere
|
|
350
|
+
2. **Be descriptive** - Clear, action-oriented names
|
|
351
|
+
3. **Be specific** - Avoid generic catch-all events
|
|
352
|
+
4. **Plan parameters** - Document required vs optional
|
|
353
|
+
5. **Validate values** - Check before sending
|
|
354
|
+
|
|
355
|
+
### Documentation
|
|
356
|
+
|
|
357
|
+
Document each custom event:
|
|
358
|
+
|
|
359
|
+
```markdown
|
|
360
|
+
## Event: demo_requested
|
|
361
|
+
|
|
362
|
+
**Description:** User requested a product demonstration
|
|
363
|
+
|
|
364
|
+
**Parameters:**
|
|
365
|
+
| Name | Type | Required | Description |
|
|
366
|
+
|------|------|----------|-------------|
|
|
367
|
+
| demo_type | string | Yes | Type of demo requested |
|
|
368
|
+
| industry | string | No | User's industry |
|
|
369
|
+
| company_size | string | No | Size category |
|
|
370
|
+
|
|
371
|
+
**Example:**
|
|
372
|
+
gtag('event', 'demo_requested', {
|
|
373
|
+
'demo_type': 'product_walkthrough',
|
|
374
|
+
'industry': 'technology'
|
|
375
|
+
});
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Version Control
|
|
379
|
+
|
|
380
|
+
Track event changes:
|
|
381
|
+
- Document when events added/modified
|
|
382
|
+
- Include in code review process
|
|
383
|
+
- Update documentation on changes
|