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.
Files changed (34) hide show
  1. package/CLAUDE.md +307 -21
  2. package/dist/assets/js/core/auth.js +5 -4
  3. package/dist/assets/js/core/cookieconsent.js +24 -17
  4. package/dist/assets/js/core/exit-popup.js +15 -12
  5. package/dist/assets/js/core/social-sharing.js +8 -4
  6. package/dist/assets/js/libs/auth/pages.js +14 -13
  7. package/dist/assets/js/libs/dev.js +192 -129
  8. package/dist/assets/js/pages/account/index.js +3 -2
  9. package/dist/assets/js/pages/account/sections/delete.js +83 -84
  10. package/dist/assets/js/pages/account/sections/security.js +4 -1
  11. package/dist/assets/js/pages/admin/notifications/new/index.js +17 -10
  12. package/dist/assets/js/pages/blog/index.js +7 -5
  13. package/dist/assets/js/pages/contact/index.js +6 -33
  14. package/dist/assets/js/pages/download/index.js +3 -2
  15. package/dist/assets/js/pages/pricing/index.js +5 -2
  16. package/dist/assets/themes/classy/css/components/_cards.scss +2 -2
  17. package/dist/defaults/_.env +6 -0
  18. package/dist/defaults/_.gitignore +7 -1
  19. package/dist/defaults/dist/_includes/core/body.html +5 -13
  20. package/dist/defaults/dist/_includes/core/foot.html +1 -0
  21. package/dist/defaults/dist/_includes/themes/classy/frontend/sections/nav.html +51 -36
  22. package/dist/defaults/dist/_layouts/blueprint/admin/notifications/new.html +13 -2
  23. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/about.html +84 -42
  24. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/account/index.html +26 -21
  25. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/blog/index.html +72 -58
  26. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/blog/post.html +46 -29
  27. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/contact.html +36 -16
  28. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/download.html +111 -73
  29. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/index.html +111 -56
  30. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/pricing.html +127 -81
  31. package/dist/defaults/dist/pages/test/libraries/lazy-loading.html +1 -1
  32. package/dist/gulp/tasks/defaults.js +210 -1
  33. package/firebase-debug.log +378 -0
  34. 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
- ### CSS Architecture
30
- - `src/assets/css/ultimate-jekyll-manager.scss` - Main UJ stylesheet
31
- - `src/assets/css/main.scss` - Site-wide styles (runs on every page)
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
- ### JavaScript Architecture
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 Pre-rendering System
333
+ ## Icon System
174
334
 
175
- Ultimate Jekyll includes a frontmatter-based icon pre-rendering system for optimal performance.
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
- ### How It Works
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
- 1. **Define icons in page frontmatter:**
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: "apple"
184
- class: "fa-3xl"
185
- - name: "android"
186
- class: "fa-2xl"
187
- - name: "chrome"
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. **Icons are rendered in HTML** via `src/defaults/dist/_includes/core/body.html`
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
- 3. **Access icons in JavaScript:**
402
+ ### What NOT to Do
403
+
404
+ **NEVER use manual icon HTML in JavaScript:**
194
405
  ```javascript
195
- const iconHTML = webManager.utilities().getPrerenderedIcon('apple');
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
- - Easy to access via JavaScript utilities
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', fbq.pixelId, {});
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', fbq.pixelId, {
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', 'cookie_banner_shown', {
313
+ gtag('event', 'cookie_banner_show', {
314
314
  event_category: 'consent'
315
315
  });
316
- fbq('trackCustom', 'CookieBannerShown');
316
+ fbq('trackCustom', 'CookieBannerShow');
317
317
  ttq.track('ViewContent', {
318
- content_name: 'Cookie Banner'
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', 'cookie_consent_accepted', {
325
+ gtag('event', 'cookie_consent_accept', {
324
326
  event_category: 'consent',
325
327
  consent_type: config.type
326
328
  });
327
- fbq('trackCustom', 'CookieConsentAccepted');
329
+ fbq('trackCustom', 'CookieConsentAccept');
328
330
  ttq.track('ClickButton', {
329
- content_name: 'Cookie Consent Accept',
330
- content_type: 'consent'
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', 'cookie_consent_denied', {
338
+ gtag('event', 'cookie_consent_deny', {
336
339
  event_category: 'consent',
337
340
  consent_type: config.type
338
341
  });
339
- fbq('trackCustom', 'CookieConsentDenied');
342
+ fbq('trackCustom', 'CookieConsentDeny');
340
343
  ttq.track('ClickButton', {
341
- content_name: 'Cookie Consent Deny',
342
- content_type: 'consent'
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', 'cookie_consent_auto_accepted', {
351
+ gtag('event', 'cookie_consent_auto_accept', {
348
352
  event_category: 'consent',
349
353
  trigger: trigger
350
354
  });
351
- fbq('trackCustom', 'CookieConsentAutoAccepted', {
355
+ fbq('trackCustom', 'CookieConsentAutoAccept', {
352
356
  trigger: trigger
353
357
  });
354
358
  ttq.track('ViewContent', {
355
- content_name: 'Cookie Consent Auto Accept',
356
- content_type: trigger
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', 'cookie_policy_reopened', {
366
+ gtag('event', 'cookie_policy_reopen', {
362
367
  event_category: 'consent'
363
368
  });
364
- fbq('trackCustom', 'CookiePolicyReopened');
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', 'exit_popup_shown', {
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', 'ExitPopupShown', {
187
- content_name: config.title,
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
- content_name: 'Exit Popup',
193
- content_type: config.title
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
- content_name: 'Exit Popup CTA',
211
- content_type: config.okButton?.text || 'OK'
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', 'exit_popup_dismissed', {
218
+ gtag('event', 'exit_popup_dismiss', {
217
219
  event_category: 'engagement',
218
220
  event_label: config.title
219
221
  });
220
222
 
221
- fbq('trackCustom', 'ExitPopupDismissed', {
222
- content_name: config.title
223
+ fbq('trackCustom', 'ExitPopupDismiss', {
224
+ content_name: 'Exit Popup Dismiss'
223
225
  });
224
226
 
225
227
  ttq.track('ViewContent', {
226
- content_name: 'Exit Popup Dismissed',
227
- content_type: config.title
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
- content_name: shareConfig.title,
306
- content_url: shareConfig.url,
307
- share_method: platformKey
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
- content_name: 'Copy Link'
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
- content_name: 'Account',
639
- content_id: userId,
640
- status: 'success'
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: 'Account',
657
- status: 'success',
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
- content_name: 'Account',
665
- content_id: userId,
666
- status: 'success'
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
- content_name: 'Password Reset',
687
- content_type: 'account_recovery'
686
+ content_id: 'password-reset',
687
+ content_type: 'product',
688
+ content_name: 'Password Reset'
688
689
  });
689
690
  }
690
691
  }