ultimate-jekyll-manager 0.0.118 → 0.0.119
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/CLAUDE.md +307 -21
- package/dist/assets/js/core/auth.js +5 -4
- package/dist/assets/js/core/cookieconsent.js +24 -17
- package/dist/assets/js/core/exit-popup.js +15 -12
- package/dist/assets/js/core/social-sharing.js +8 -4
- package/dist/assets/js/libs/auth/pages.js +14 -13
- package/dist/assets/js/libs/dev.js +192 -129
- package/dist/assets/js/pages/account/index.js +3 -2
- package/dist/assets/js/pages/account/sections/delete.js +83 -84
- package/dist/assets/js/pages/account/sections/security.js +4 -1
- package/dist/assets/js/pages/admin/notifications/new/index.js +17 -10
- package/dist/assets/js/pages/blog/index.js +7 -5
- package/dist/assets/js/pages/contact/index.js +6 -33
- package/dist/assets/js/pages/download/index.js +3 -2
- package/dist/assets/js/pages/pricing/index.js +5 -2
- package/dist/assets/themes/classy/css/components/_cards.scss +2 -2
- package/dist/defaults/_.env +6 -0
- package/dist/defaults/_.gitignore +7 -1
- package/dist/defaults/dist/_includes/core/body.html +5 -13
- package/dist/defaults/dist/_includes/core/foot.html +1 -0
- package/dist/defaults/dist/_includes/themes/classy/frontend/sections/nav.html +51 -36
- package/dist/defaults/dist/_layouts/blueprint/admin/notifications/new.html +13 -2
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/about.html +84 -42
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/account/index.html +26 -21
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/blog/index.html +72 -58
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/blog/post.html +46 -29
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/contact.html +36 -16
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/download.html +111 -73
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/index.html +111 -56
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/pricing.html +127 -81
- package/dist/defaults/dist/pages/test/libraries/lazy-loading.html +1 -1
- package/dist/gulp/tasks/defaults.js +210 -1
- package/firebase-debug.log +378 -0
- package/package.json +2 -2
package/CLAUDE.md
CHANGED
|
@@ -26,19 +26,179 @@ The local development server URL is stored in `.temp/_config_browsersync.yml` in
|
|
|
26
26
|
|
|
27
27
|
## Asset Organization
|
|
28
28
|
|
|
29
|
-
###
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
### Ultimate Jekyll Manager Files (THIS project)
|
|
30
|
+
|
|
31
|
+
**CSS:**
|
|
32
|
+
- `src/assets/css/ultimate-jekyll-manager.scss` - Main UJ stylesheet (provides core styles)
|
|
32
33
|
- `src/assets/css/global/` - Global UJ styles
|
|
33
|
-
- `src/assets/css/pages/` - Page-specific styles
|
|
34
|
+
- `src/assets/css/pages/` - Page-specific styles provided by UJ
|
|
34
35
|
- Format: `src/assets/css/pages/[page-name]/index.scss`
|
|
36
|
+
- Example: `src/assets/css/pages/download/index.scss`
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
- `src/assets/js/ultimate-jekyll-manager.js` - Main UJ JavaScript entry point
|
|
38
|
-
- `src/assets/js/main.js` - Site-wide JavaScript (runs on every page)
|
|
38
|
+
**JavaScript:**
|
|
39
|
+
- `src/assets/js/ultimate-jekyll-manager.js` - Main UJ JavaScript entry point (provides core functionality)
|
|
39
40
|
- `src/assets/js/core/` - Core UJ modules
|
|
40
|
-
- `src/assets/js/pages/` - Page-specific JavaScript
|
|
41
|
+
- `src/assets/js/pages/` - Page-specific JavaScript provided by UJ
|
|
41
42
|
- Format: `src/assets/js/pages/[page-name]/index.js`
|
|
43
|
+
- Example: `src/assets/js/pages/download/index.js`
|
|
44
|
+
- `src/assets/js/libs/` - UJ library modules (prerendered-icons, form-manager, authorized-fetch, etc.)
|
|
45
|
+
|
|
46
|
+
**Default Pages & Layouts:**
|
|
47
|
+
|
|
48
|
+
UJ provides default page templates and layouts in `src/defaults/dist/` that are copied to consuming projects. These are NOT meant to be edited by users.
|
|
49
|
+
|
|
50
|
+
- Format: `src/defaults/dist/_layouts/themes/[theme-id]/frontend/pages/[page-name].html`
|
|
51
|
+
- Examples:
|
|
52
|
+
- `src/defaults/dist/_layouts/themes/classy/frontend/pages/download.html`
|
|
53
|
+
- `src/defaults/dist/_layouts/themes/classy/frontend/pages/pricing.html`
|
|
54
|
+
- `src/defaults/dist/_layouts/themes/classy/frontend/pages/payment/checkout.html`
|
|
55
|
+
- `src/defaults/dist/_layouts/themes/classy/frontend/pages/payment/confirmation.html`
|
|
56
|
+
- `src/defaults/dist/_layouts/themes/classy/frontend/pages/contact.html`
|
|
57
|
+
- Core layouts:
|
|
58
|
+
- `src/defaults/dist/_layouts/core/root.html` - Root HTML wrapper
|
|
59
|
+
- `src/defaults/dist/_layouts/themes/[theme-id]/frontend/core/base.html` - Theme base layout
|
|
60
|
+
|
|
61
|
+
**Complete UJ Page Example:**
|
|
62
|
+
- **HTML:** `src/defaults/dist/_layouts/themes/classy/frontend/pages/download.html`
|
|
63
|
+
- **CSS:** `src/assets/css/pages/download/index.scss`
|
|
64
|
+
- **JS:** `src/assets/js/pages/download/index.js`
|
|
65
|
+
|
|
66
|
+
These files serve as blueprints and reference implementations. When building custom pages in consuming projects, reference these for patterns and best practices.
|
|
67
|
+
|
|
68
|
+
**IMPORTANT:** Consuming projects CAN create files with the same paths in their own `src/` directory to override UJ defaults, but this should ONLY be done when absolutely necessary. Prefer using `src/pages/` and `src/_layouts/` for custom pages instead of overriding UJ default files.
|
|
69
|
+
|
|
70
|
+
### Section Configuration Files (JSON)
|
|
71
|
+
|
|
72
|
+
UJ provides JSON configuration files for common sections like navigation and footer. These JSON files are consumed by corresponding HTML templates during the build process.
|
|
73
|
+
|
|
74
|
+
**Configuration Files:**
|
|
75
|
+
- `src/defaults/src/_includes/frontend/sections/nav.json` - Navigation configuration
|
|
76
|
+
- `src/defaults/src/_includes/frontend/sections/footer.json` - Footer configuration
|
|
77
|
+
|
|
78
|
+
**How It Works:**
|
|
79
|
+
1. JSON files contain structured data (links, labels, settings)
|
|
80
|
+
2. HTML templates in `src/defaults/dist/_includes/themes/[theme-id]/frontend/sections/` read and render this data
|
|
81
|
+
3. The build process converts `.json` → data loaded by `.html` templates
|
|
82
|
+
|
|
83
|
+
**Customizing Navigation/Footer:**
|
|
84
|
+
|
|
85
|
+
Consuming projects should create their own JSON files in `src/_includes/frontend/sections/`:
|
|
86
|
+
- `src/_includes/frontend/sections/nav.json`
|
|
87
|
+
- `src/_includes/frontend/sections/footer.json`
|
|
88
|
+
|
|
89
|
+
**Example: Footer Configuration**
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
logo: {
|
|
94
|
+
href: '/',
|
|
95
|
+
class: 'filter-adaptive',
|
|
96
|
+
text: '{{ site.brand.name }}',
|
|
97
|
+
description: '{{ site.meta.description }}',
|
|
98
|
+
},
|
|
99
|
+
links: [
|
|
100
|
+
{
|
|
101
|
+
label: 'Company',
|
|
102
|
+
href: null,
|
|
103
|
+
links: [
|
|
104
|
+
{
|
|
105
|
+
label: 'About Us',
|
|
106
|
+
href: '/about',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
label: 'Pricing',
|
|
110
|
+
href: '/pricing',
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
socials: {
|
|
116
|
+
enabled: true,
|
|
117
|
+
},
|
|
118
|
+
copyright: {
|
|
119
|
+
enabled: true,
|
|
120
|
+
text: null,
|
|
121
|
+
},
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Note:** These are JSON5 files (support comments, trailing commas, unquoted keys). The corresponding HTML templates automatically process these files during the build.
|
|
126
|
+
|
|
127
|
+
### Customizing Default Pages via Frontmatter
|
|
128
|
+
|
|
129
|
+
**BEST PRACTICE:** UJ default pages are designed to be customized through frontmatter WITHOUT writing any HTML. Consuming projects can create a simple page that includes ONLY frontmatter to configure the default page's behavior.
|
|
130
|
+
|
|
131
|
+
**How It Works:**
|
|
132
|
+
1. UJ default pages use `page.resolved` to access merged frontmatter (site → layout → page)
|
|
133
|
+
2. **IMPORTANT:** Before customizing, READ the UJ default page in `src/defaults/dist/_layouts/` to understand available frontmatter options and how they're used
|
|
134
|
+
3. Consuming projects create a page in `src/pages/` with custom frontmatter
|
|
135
|
+
4. The page uses a UJ layout (e.g., `blueprint/pricing`)
|
|
136
|
+
5. Frontmatter overrides default values without any HTML
|
|
137
|
+
|
|
138
|
+
**Example: Customizing the Pricing Page**
|
|
139
|
+
|
|
140
|
+
**Step 1:** Read the UJ default pricing page to see available frontmatter options:
|
|
141
|
+
- File: `src/defaults/dist/_layouts/themes/classy/frontend/pages/pricing.html`
|
|
142
|
+
- Look for frontmatter at the top and how `page.resolved.pricing` is used in the HTML
|
|
143
|
+
|
|
144
|
+
**Step 2:** In consuming project, create `src/pages/pricing.html`:
|
|
145
|
+
|
|
146
|
+
```yaml
|
|
147
|
+
---
|
|
148
|
+
### ALL PAGES ###
|
|
149
|
+
layout: blueprint/pricing
|
|
150
|
+
permalink: /pricing
|
|
151
|
+
|
|
152
|
+
### PAGE CONFIG ###
|
|
153
|
+
pricing:
|
|
154
|
+
price_per_unit:
|
|
155
|
+
enabled: true
|
|
156
|
+
feature_id: "credits"
|
|
157
|
+
label: "credit"
|
|
158
|
+
plans:
|
|
159
|
+
- id: "basic"
|
|
160
|
+
name: "Basic"
|
|
161
|
+
tagline: "best for getting started"
|
|
162
|
+
url: "/download"
|
|
163
|
+
pricing:
|
|
164
|
+
monthly: 0
|
|
165
|
+
annually: 0
|
|
166
|
+
features:
|
|
167
|
+
- id: "credits"
|
|
168
|
+
name: "Credits"
|
|
169
|
+
value: 1
|
|
170
|
+
icon: "sparkles"
|
|
171
|
+
...
|
|
172
|
+
---
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
That's it! No HTML needed. The UJ pricing layout reads `page.resolved.pricing` and renders the plans accordingly.
|
|
176
|
+
|
|
177
|
+
**When to Use Frontmatter Customization:**
|
|
178
|
+
- ✅ Customizing UJ default pages (pricing, contact, download, etc.)
|
|
179
|
+
- ✅ Changing configuration without touching HTML
|
|
180
|
+
- ✅ Maintaining upgradability when UJ updates
|
|
181
|
+
|
|
182
|
+
**When to Create Custom Pages:**
|
|
183
|
+
- ❌ Building entirely new page types
|
|
184
|
+
- ❌ Needing custom HTML structure
|
|
185
|
+
- ❌ Pages with unique layouts not provided by UJ
|
|
186
|
+
|
|
187
|
+
### Consuming Project Files
|
|
188
|
+
|
|
189
|
+
**CSS:**
|
|
190
|
+
- `src/assets/css/main.scss` - Site-wide custom styles (runs on every page, edits by consuming project)
|
|
191
|
+
- `src/assets/css/pages/` - Page-specific custom styles
|
|
192
|
+
- Format: `src/assets/css/pages/[page-name]/index.scss`
|
|
193
|
+
|
|
194
|
+
**JavaScript:**
|
|
195
|
+
- `src/assets/js/main.js` - Site-wide custom JavaScript (runs on every page, edits by consuming project)
|
|
196
|
+
- `src/assets/js/pages/` - Page-specific custom JavaScript
|
|
197
|
+
- Format: `src/assets/js/pages/[page-name]/index.js`
|
|
198
|
+
|
|
199
|
+
**Pages & Layouts:**
|
|
200
|
+
- `src/pages/` - Individual page HTML/Markdown files
|
|
201
|
+
- `src/_layouts/` - Custom layouts for the consuming project
|
|
42
202
|
|
|
43
203
|
**Asset Loading:** Page-specific CSS/JS files are automatically included based on the page's canonical path. Override with `asset_path` frontmatter.
|
|
44
204
|
|
|
@@ -170,36 +330,95 @@ asset_path: blog/post
|
|
|
170
330
|
|
|
171
331
|
Uses `/assets/css/pages/{{ asset_path }}.bundle.css` instead of deriving from `page.canonical.path`. Useful when multiple pages share assets (e.g., all blog posts).
|
|
172
332
|
|
|
173
|
-
## Icon
|
|
333
|
+
## Icon System
|
|
174
334
|
|
|
175
|
-
Ultimate Jekyll
|
|
335
|
+
Ultimate Jekyll uses Font Awesome icons but does NOT include the Font Awesome JavaScript or CSS library. All icons must be rendered server-side using Jekyll's `{% uj_icon %}` tag.
|
|
176
336
|
|
|
177
|
-
###
|
|
337
|
+
### When to Use `{% uj_icon %}` vs Prerendered Icons
|
|
338
|
+
|
|
339
|
+
**IMPORTANT:** Use the correct method based on WHERE the icon will be used:
|
|
340
|
+
|
|
341
|
+
#### Use `{% uj_icon %}` in HTML/Liquid Templates
|
|
342
|
+
|
|
343
|
+
When icons are part of the static HTML template, use `{% uj_icon %}` directly:
|
|
344
|
+
|
|
345
|
+
```liquid
|
|
346
|
+
<!-- Alerts -->
|
|
347
|
+
<div class="alert alert-success">
|
|
348
|
+
{% uj_icon "circle-check", "fa-sm" %} Success message
|
|
349
|
+
</div>
|
|
350
|
+
|
|
351
|
+
<!-- Buttons -->
|
|
352
|
+
<button class="btn btn-primary">
|
|
353
|
+
{% uj_icon "paper-plane", "fa-md me-2" %}
|
|
354
|
+
Send
|
|
355
|
+
</button>
|
|
356
|
+
|
|
357
|
+
<!-- Labels -->
|
|
358
|
+
<label>
|
|
359
|
+
{% uj_icon "envelope", "fa-sm me-1 text-info" %}
|
|
360
|
+
Email
|
|
361
|
+
</label>
|
|
362
|
+
```
|
|
178
363
|
|
|
179
|
-
|
|
364
|
+
**Use this when:**
|
|
365
|
+
- The icon is in a Jekyll template (.html file)
|
|
366
|
+
- The icon is static and known at build time
|
|
367
|
+
- The icon is part of the page structure
|
|
368
|
+
|
|
369
|
+
#### Use Prerendered Icons in JavaScript
|
|
370
|
+
|
|
371
|
+
When icons need to be dynamically inserted via JavaScript, pre-render them in frontmatter and access them via the library:
|
|
372
|
+
|
|
373
|
+
**1. Add icons to page frontmatter:**
|
|
180
374
|
```yaml
|
|
181
375
|
---
|
|
182
376
|
prerender_icons:
|
|
183
|
-
- name: "
|
|
184
|
-
class: "fa-
|
|
185
|
-
- name: "
|
|
186
|
-
class: "fa-
|
|
187
|
-
- name: "
|
|
377
|
+
- name: "mobile"
|
|
378
|
+
class: "fa-sm me-1"
|
|
379
|
+
- name: "envelope"
|
|
380
|
+
class: "fa-sm me-1"
|
|
381
|
+
- name: "bell"
|
|
382
|
+
class: "fa-sm me-1"
|
|
188
383
|
---
|
|
189
384
|
```
|
|
190
385
|
|
|
191
|
-
2.
|
|
386
|
+
**2. Import the library in JavaScript:**
|
|
387
|
+
```javascript
|
|
388
|
+
import { getPrerenderedIcon } from '__main_assets__/js/libs/prerendered-icons.js';
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
**3. Use in your code:**
|
|
392
|
+
```javascript
|
|
393
|
+
const iconHTML = getPrerenderedIcon('mobile');
|
|
394
|
+
$badge.innerHTML = `${iconHTML}Push Notification`;
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
**Use this when:**
|
|
398
|
+
- Icons are dynamically inserted via JavaScript
|
|
399
|
+
- Icons are part of dynamically generated content
|
|
400
|
+
- Icons are added to elements created with `document.createElement()`
|
|
192
401
|
|
|
193
|
-
|
|
402
|
+
### What NOT to Do
|
|
403
|
+
|
|
404
|
+
**NEVER use manual icon HTML in JavaScript:**
|
|
194
405
|
```javascript
|
|
195
|
-
|
|
406
|
+
// ❌ WRONG - Bootstrap Icons (we don't use Bootstrap Icons)
|
|
407
|
+
$el.innerHTML = '<i class="bi bi-check-circle"></i> Text';
|
|
408
|
+
|
|
409
|
+
// ❌ WRONG - Manual Font Awesome (we don't have FA JS/CSS)
|
|
410
|
+
$el.innerHTML = '<i class="fa-solid fa-check"></i> Text';
|
|
411
|
+
|
|
412
|
+
// ✅ CORRECT - Use prerendered icons
|
|
413
|
+
const iconHTML = getPrerenderedIcon('circle-check');
|
|
414
|
+
$el.innerHTML = `${iconHTML} Text`;
|
|
196
415
|
```
|
|
197
416
|
|
|
198
417
|
### Benefits
|
|
199
418
|
- Icons are rendered server-side with proper Font Awesome classes
|
|
200
419
|
- No client-side icon generation overhead
|
|
201
420
|
- Consistent icon styling across the application
|
|
202
|
-
-
|
|
421
|
+
- No Font Awesome JavaScript/CSS library needed
|
|
203
422
|
|
|
204
423
|
## CSS Guidelines
|
|
205
424
|
|
|
@@ -393,6 +612,73 @@ const formManager = new FormManager('#my-form', options);
|
|
|
393
612
|
**Reference:** `src/assets/js/libs/form-manager.js`
|
|
394
613
|
**Example:** `src/assets/js/pages/contact/index.js`
|
|
395
614
|
|
|
615
|
+
## Analytics & Tracking
|
|
616
|
+
|
|
617
|
+
Ultimate Jekyll uses three tracking platforms: Google Analytics (gtag), Facebook Pixel (fbq), and TikTok Pixel (ttq).
|
|
618
|
+
|
|
619
|
+
### Tracking Guidelines
|
|
620
|
+
|
|
621
|
+
**IMPORTANT Rules:**
|
|
622
|
+
- Track important user events with `gtag()`, `fbq()`, and `ttq()` functions
|
|
623
|
+
- NEVER add conditional checks for tracking functions (e.g., `if (typeof gtag !== 'undefined')`)
|
|
624
|
+
- Always assume tracking functions exist - they're globally available or stubbed
|
|
625
|
+
- Reference standard events documentation before implementing custom tracking
|
|
626
|
+
|
|
627
|
+
**Standard Events Documentation:**
|
|
628
|
+
- **Google Analytics GA4:** https://developers.google.com/analytics/devguides/collection/ga4/reference/events
|
|
629
|
+
- **Facebook Pixel:** https://www.facebook.com/business/help/402791146561655?id=1205376682832142
|
|
630
|
+
- **TikTok Pixel:** https://ads.tiktok.com/help/article/standard-events-parameters?redirected=2
|
|
631
|
+
|
|
632
|
+
### Platform-Specific Requirements
|
|
633
|
+
|
|
634
|
+
#### TikTok Pixel Requirements
|
|
635
|
+
TikTok has strict validation requirements:
|
|
636
|
+
|
|
637
|
+
**Required Parameters:**
|
|
638
|
+
- `content_id` - MUST be included in all events
|
|
639
|
+
|
|
640
|
+
**Valid Content Types:**
|
|
641
|
+
- `"product"`
|
|
642
|
+
- `"product_group"`
|
|
643
|
+
- `"destination"`
|
|
644
|
+
- `"hotel"`
|
|
645
|
+
- `"flight"`
|
|
646
|
+
- `"vehicle"`
|
|
647
|
+
|
|
648
|
+
Any other content type will generate a validation error.
|
|
649
|
+
|
|
650
|
+
**Example:**
|
|
651
|
+
```javascript
|
|
652
|
+
// ✅ CORRECT
|
|
653
|
+
ttq.track('ViewContent', {
|
|
654
|
+
content_id: 'product-123',
|
|
655
|
+
content_type: 'product'
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
// ❌ WRONG - Missing content_id
|
|
659
|
+
ttq.track('ViewContent', {
|
|
660
|
+
content_type: 'product'
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
// ❌ WRONG - Invalid content_type
|
|
664
|
+
ttq.track('ViewContent', {
|
|
665
|
+
content_id: 'product-123',
|
|
666
|
+
content_type: 'custom' // Not in approved list
|
|
667
|
+
});
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
### Tracking Implementation
|
|
671
|
+
|
|
672
|
+
**IMPORTANT:** Always track events to ALL THREE platforms in this order:
|
|
673
|
+
1. Google Analytics (gtag)
|
|
674
|
+
2. Facebook Pixel (fbq)
|
|
675
|
+
3. TikTok Pixel (ttq)
|
|
676
|
+
|
|
677
|
+
Track events directly without existence checks. All three tracking calls should be made together for every event.
|
|
678
|
+
|
|
679
|
+
**Development Mode:**
|
|
680
|
+
In development mode, all tracking calls are intercepted and logged to the console for debugging. See `src/assets/js/libs/dev.js` for implementation.
|
|
681
|
+
|
|
396
682
|
## Audit Workflow
|
|
397
683
|
|
|
398
684
|
When fixing issues identified by the audit task (`src/gulp/tasks/audit.js`):
|
|
@@ -32,7 +32,7 @@ export default function (Manager, options) {
|
|
|
32
32
|
console.log('[Auth] state changed:', state);
|
|
33
33
|
|
|
34
34
|
// Set user ID for analytics tracking
|
|
35
|
-
setAnalyticsUserId(user);
|
|
35
|
+
setAnalyticsUserId(user, webManager);
|
|
36
36
|
|
|
37
37
|
// Check if we're in the process of signing out
|
|
38
38
|
if (authSignout === 'true' && user) {
|
|
@@ -119,9 +119,10 @@ function redirect(url, returnUrl) {
|
|
|
119
119
|
window.location.href = newURL;
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
function setAnalyticsUserId(user) {
|
|
122
|
+
function setAnalyticsUserId(user, webManager) {
|
|
123
123
|
const userId = user?.uid;
|
|
124
124
|
const email = user?.email;
|
|
125
|
+
const metaPixelId = webManager.config.tracking['meta-pixel'];
|
|
125
126
|
|
|
126
127
|
// Short-circuit if no user
|
|
127
128
|
if (!userId) {
|
|
@@ -129,7 +130,7 @@ function setAnalyticsUserId(user) {
|
|
|
129
130
|
gtag('set', { user_id: null });
|
|
130
131
|
|
|
131
132
|
// Facebook Pixel - Clear advanced matching
|
|
132
|
-
fbq('init',
|
|
133
|
+
fbq('init', metaPixelId, {});
|
|
133
134
|
|
|
134
135
|
// TikTok Pixel - Clear user data
|
|
135
136
|
ttq.identify({});
|
|
@@ -147,7 +148,7 @@ function setAnalyticsUserId(user) {
|
|
|
147
148
|
});
|
|
148
149
|
|
|
149
150
|
// Facebook Pixel - Set advanced matching with user data
|
|
150
|
-
fbq('init',
|
|
151
|
+
fbq('init', metaPixelId, {
|
|
151
152
|
external_id: userId,
|
|
152
153
|
// em: email ? btoa(email.toLowerCase().trim()) : undefined,
|
|
153
154
|
em: email,
|
|
@@ -310,59 +310,66 @@ export default function (Manager, options) {
|
|
|
310
310
|
|
|
311
311
|
// Tracking functions
|
|
312
312
|
function trackCookieBannerShown() {
|
|
313
|
-
gtag('event', '
|
|
313
|
+
gtag('event', 'cookie_banner_show', {
|
|
314
314
|
event_category: 'consent'
|
|
315
315
|
});
|
|
316
|
-
fbq('trackCustom', '
|
|
316
|
+
fbq('trackCustom', 'CookieBannerShow');
|
|
317
317
|
ttq.track('ViewContent', {
|
|
318
|
-
|
|
318
|
+
content_id: 'cookie-banner-show',
|
|
319
|
+
content_type: 'product',
|
|
320
|
+
content_name: 'Cookie Banner Show'
|
|
319
321
|
});
|
|
320
322
|
}
|
|
321
323
|
|
|
322
324
|
function trackCookieAccepted() {
|
|
323
|
-
gtag('event', '
|
|
325
|
+
gtag('event', 'cookie_consent_accept', {
|
|
324
326
|
event_category: 'consent',
|
|
325
327
|
consent_type: config.type
|
|
326
328
|
});
|
|
327
|
-
fbq('trackCustom', '
|
|
329
|
+
fbq('trackCustom', 'CookieConsentAccept');
|
|
328
330
|
ttq.track('ClickButton', {
|
|
329
|
-
|
|
330
|
-
content_type: '
|
|
331
|
+
content_id: 'cookie-consent-accept',
|
|
332
|
+
content_type: 'product',
|
|
333
|
+
content_name: 'Cookie Consent Accept'
|
|
331
334
|
});
|
|
332
335
|
}
|
|
333
336
|
|
|
334
337
|
function trackCookieDenied() {
|
|
335
|
-
gtag('event', '
|
|
338
|
+
gtag('event', 'cookie_consent_deny', {
|
|
336
339
|
event_category: 'consent',
|
|
337
340
|
consent_type: config.type
|
|
338
341
|
});
|
|
339
|
-
fbq('trackCustom', '
|
|
342
|
+
fbq('trackCustom', 'CookieConsentDeny');
|
|
340
343
|
ttq.track('ClickButton', {
|
|
341
|
-
|
|
342
|
-
content_type: '
|
|
344
|
+
content_id: 'cookie-consent-deny',
|
|
345
|
+
content_type: 'product',
|
|
346
|
+
content_name: 'Cookie Consent Deny'
|
|
343
347
|
});
|
|
344
348
|
}
|
|
345
349
|
|
|
346
350
|
function trackCookieAutoAccepted(trigger) {
|
|
347
|
-
gtag('event', '
|
|
351
|
+
gtag('event', 'cookie_consent_auto_accept', {
|
|
348
352
|
event_category: 'consent',
|
|
349
353
|
trigger: trigger
|
|
350
354
|
});
|
|
351
|
-
fbq('trackCustom', '
|
|
355
|
+
fbq('trackCustom', 'CookieConsentAutoAccept', {
|
|
352
356
|
trigger: trigger
|
|
353
357
|
});
|
|
354
358
|
ttq.track('ViewContent', {
|
|
355
|
-
|
|
356
|
-
content_type:
|
|
359
|
+
content_id: 'cookie-consent-auto-accept',
|
|
360
|
+
content_type: 'product',
|
|
361
|
+
content_name: 'Cookie Consent Auto Accept'
|
|
357
362
|
});
|
|
358
363
|
}
|
|
359
364
|
|
|
360
365
|
function trackCookiePolicyReopened() {
|
|
361
|
-
gtag('event', '
|
|
366
|
+
gtag('event', 'cookie_policy_reopen', {
|
|
362
367
|
event_category: 'consent'
|
|
363
368
|
});
|
|
364
|
-
fbq('trackCustom', '
|
|
369
|
+
fbq('trackCustom', 'CookiePolicyReopen');
|
|
365
370
|
ttq.track('ClickButton', {
|
|
371
|
+
content_id: 'cookie-policy-reopen',
|
|
372
|
+
content_type: 'product',
|
|
366
373
|
content_name: 'Cookie Policy Reopen'
|
|
367
374
|
});
|
|
368
375
|
}
|
|
@@ -177,20 +177,21 @@ export default function (Manager, options) {
|
|
|
177
177
|
|
|
178
178
|
// Tracking functions
|
|
179
179
|
function trackExitPopupShown() {
|
|
180
|
-
gtag('event', '
|
|
180
|
+
gtag('event', 'exit_popup_show', {
|
|
181
181
|
event_category: 'engagement',
|
|
182
182
|
event_label: config.title,
|
|
183
183
|
page_path: window.location.pathname
|
|
184
184
|
});
|
|
185
185
|
|
|
186
|
-
fbq('trackCustom', '
|
|
187
|
-
content_name:
|
|
186
|
+
fbq('trackCustom', 'ExitPopupShow', {
|
|
187
|
+
content_name: 'Exit Popup Show',
|
|
188
188
|
page_path: window.location.pathname
|
|
189
189
|
});
|
|
190
190
|
|
|
191
191
|
ttq.track('ViewContent', {
|
|
192
|
-
|
|
193
|
-
content_type:
|
|
192
|
+
content_id: 'exit-popup-show',
|
|
193
|
+
content_type: 'product',
|
|
194
|
+
content_name: 'Exit Popup Show'
|
|
194
195
|
});
|
|
195
196
|
}
|
|
196
197
|
|
|
@@ -207,24 +208,26 @@ export default function (Manager, options) {
|
|
|
207
208
|
});
|
|
208
209
|
|
|
209
210
|
ttq.track('ClickButton', {
|
|
210
|
-
|
|
211
|
-
content_type:
|
|
211
|
+
content_id: 'exit-popup-click',
|
|
212
|
+
content_type: 'product',
|
|
213
|
+
content_name: 'Exit Popup Click'
|
|
212
214
|
});
|
|
213
215
|
}
|
|
214
216
|
|
|
215
217
|
function trackExitPopupDismissed() {
|
|
216
|
-
gtag('event', '
|
|
218
|
+
gtag('event', 'exit_popup_dismiss', {
|
|
217
219
|
event_category: 'engagement',
|
|
218
220
|
event_label: config.title
|
|
219
221
|
});
|
|
220
222
|
|
|
221
|
-
fbq('trackCustom', '
|
|
222
|
-
content_name:
|
|
223
|
+
fbq('trackCustom', 'ExitPopupDismiss', {
|
|
224
|
+
content_name: 'Exit Popup Dismiss'
|
|
223
225
|
});
|
|
224
226
|
|
|
225
227
|
ttq.track('ViewContent', {
|
|
226
|
-
|
|
227
|
-
content_type:
|
|
228
|
+
content_id: 'exit-popup-dismiss',
|
|
229
|
+
content_type: 'product',
|
|
230
|
+
content_name: 'Exit Popup Dismiss'
|
|
228
231
|
});
|
|
229
232
|
}
|
|
230
233
|
};
|
|
@@ -289,6 +289,8 @@ export default function (Manager, options) {
|
|
|
289
289
|
|
|
290
290
|
// Tracking functions
|
|
291
291
|
function trackShare(platformKey, shareConfig) {
|
|
292
|
+
const platformName = platforms[platformKey]?.name || platformKey;
|
|
293
|
+
|
|
292
294
|
gtag('event', 'share', {
|
|
293
295
|
method: platformKey,
|
|
294
296
|
content_type: 'article',
|
|
@@ -302,9 +304,9 @@ export default function (Manager, options) {
|
|
|
302
304
|
});
|
|
303
305
|
|
|
304
306
|
ttq.track('Share', {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
307
|
+
content_id: `social-share-${platformKey}`,
|
|
308
|
+
content_type: 'product',
|
|
309
|
+
content_name: `Social Share ${platformName}`
|
|
308
310
|
});
|
|
309
311
|
}
|
|
310
312
|
|
|
@@ -319,7 +321,9 @@ export default function (Manager, options) {
|
|
|
319
321
|
});
|
|
320
322
|
|
|
321
323
|
ttq.track('ClickButton', {
|
|
322
|
-
|
|
324
|
+
content_id: 'social-share-copy-link',
|
|
325
|
+
content_type: 'product',
|
|
326
|
+
content_name: 'Social Share Copy Link'
|
|
323
327
|
});
|
|
324
328
|
}
|
|
325
329
|
};
|
|
@@ -620,6 +620,7 @@ export default function (Manager) {
|
|
|
620
620
|
|
|
621
621
|
function trackLogin(method, user) {
|
|
622
622
|
const userId = user.uid;
|
|
623
|
+
const methodName = method.charAt(0).toUpperCase() + method.slice(1);
|
|
623
624
|
|
|
624
625
|
// Google Analytics 4
|
|
625
626
|
gtag('event', 'login', {
|
|
@@ -629,21 +630,22 @@ export default function (Manager) {
|
|
|
629
630
|
|
|
630
631
|
// Facebook Pixel
|
|
631
632
|
fbq('trackCustom', 'Login', {
|
|
633
|
+
content_name: `Account Login ${methodName}`,
|
|
632
634
|
method: method,
|
|
633
|
-
status: 'success'
|
|
634
635
|
});
|
|
635
636
|
|
|
636
637
|
// TikTok Pixel
|
|
637
638
|
ttq.track('Login', {
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
639
|
+
content_id: `account-login-${method}`,
|
|
640
|
+
content_type: 'product',
|
|
641
|
+
content_name: `Account Login ${methodName}`
|
|
641
642
|
});
|
|
642
643
|
}
|
|
643
644
|
|
|
644
645
|
// Analytics tracking functions
|
|
645
646
|
function trackSignup(method, user) {
|
|
646
647
|
const userId = user.uid;
|
|
648
|
+
const methodName = method.charAt(0).toUpperCase() + method.slice(1);
|
|
647
649
|
|
|
648
650
|
// Google Analytics 4
|
|
649
651
|
gtag('event', 'sign_up', {
|
|
@@ -653,17 +655,15 @@ export default function (Manager) {
|
|
|
653
655
|
|
|
654
656
|
// Facebook Pixel
|
|
655
657
|
fbq('track', 'CompleteRegistration', {
|
|
656
|
-
content_name:
|
|
657
|
-
|
|
658
|
-
value: 0,
|
|
659
|
-
currency: 'USD'
|
|
658
|
+
content_name: `Account Registration ${methodName}`,
|
|
659
|
+
method: method,
|
|
660
660
|
});
|
|
661
661
|
|
|
662
662
|
// TikTok Pixel
|
|
663
663
|
ttq.track('CompleteRegistration', {
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
664
|
+
content_id: `account-registration-${method}`,
|
|
665
|
+
content_type: 'product',
|
|
666
|
+
content_name: `Account Registration ${methodName}`
|
|
667
667
|
});
|
|
668
668
|
}
|
|
669
669
|
|
|
@@ -683,8 +683,9 @@ export default function (Manager) {
|
|
|
683
683
|
|
|
684
684
|
// TikTok Pixel
|
|
685
685
|
ttq.track('SubmitForm', {
|
|
686
|
-
|
|
687
|
-
content_type: '
|
|
686
|
+
content_id: 'password-reset',
|
|
687
|
+
content_type: 'product',
|
|
688
|
+
content_name: 'Password Reset'
|
|
688
689
|
});
|
|
689
690
|
}
|
|
690
691
|
}
|