@thead-vantage/react 2.12.0 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/lib/ads.ts +38 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thead-vantage/react",
3
- "version": "2.12.0",
3
+ "version": "2.14.0",
4
4
  "description": "React components and utilities for TheAd Vantage ad platform integration",
5
5
  "main": "./src/index.ts",
6
6
  "module": "./src/index.ts",
package/src/lib/ads.ts CHANGED
@@ -378,6 +378,15 @@ export async function trackImpression(adId: string): Promise<void> {
378
378
  trackingUrl = trackingUrl.replace(/\/$/, '') + '/api/ads/track';
379
379
  }
380
380
 
381
+ // Normalize URL to HTTPS and ensure www (avoid 308 redirects)
382
+ if (trackingUrl.startsWith('http://')) {
383
+ trackingUrl = trackingUrl.replace('http://', 'https://');
384
+ }
385
+ // Ensure www to avoid redirects
386
+ if (trackingUrl.includes('thead-vantage.com') && !trackingUrl.includes('www.')) {
387
+ trackingUrl = trackingUrl.replace('thead-vantage.com', 'www.thead-vantage.com');
388
+ }
389
+
381
390
  // Check if we should skip tracking (dev mode)
382
391
  const useDevFlags = shouldUseDevFlags();
383
392
  if (useDevFlags) {
@@ -387,6 +396,8 @@ export async function trackImpression(adId: string): Promise<void> {
387
396
 
388
397
  const response = await fetch(trackingUrl, {
389
398
  method: 'POST',
399
+ mode: 'cors', // Explicitly enable CORS
400
+ credentials: 'omit', // Don't send cookies
390
401
  headers: {
391
402
  'Content-Type': 'application/json',
392
403
  'Accept': 'application/json',
@@ -407,7 +418,14 @@ export async function trackImpression(adId: string): Promise<void> {
407
418
  console.log(`[DEV] Impression tracking skipped for ad: ${adId}`);
408
419
  }
409
420
  } catch (error) {
410
- console.error('Error tracking impression:', error);
421
+ // Handle CORS errors gracefully (tracking failures shouldn't break the app)
422
+ if (error instanceof TypeError && (error.message.includes('CORS') || error.message.includes('Failed to fetch'))) {
423
+ // This is expected until the server configures CORS for /api/ads/track endpoint
424
+ // The ad still displays correctly, tracking just won't work until server-side CORS is fixed
425
+ console.debug(`[AdBanner] Tracking impression failed (CORS): The /api/ads/track endpoint needs CORS headers configured on the server. Ad still displayed successfully.`);
426
+ } else {
427
+ console.error('Error tracking impression:', error);
428
+ }
411
429
  // Don't throw - tracking failures shouldn't break the app
412
430
  }
413
431
  }
@@ -430,6 +448,15 @@ export async function trackClick(adId: string): Promise<void> {
430
448
  trackingUrl = trackingUrl.replace(/\/$/, '') + '/api/ads/track';
431
449
  }
432
450
 
451
+ // Normalize URL to HTTPS and ensure www (avoid 308 redirects)
452
+ if (trackingUrl.startsWith('http://')) {
453
+ trackingUrl = trackingUrl.replace('http://', 'https://');
454
+ }
455
+ // Ensure www to avoid redirects
456
+ if (trackingUrl.includes('thead-vantage.com') && !trackingUrl.includes('www.')) {
457
+ trackingUrl = trackingUrl.replace('thead-vantage.com', 'www.thead-vantage.com');
458
+ }
459
+
433
460
  // Check if we should skip tracking (dev mode)
434
461
  const useDevFlags = shouldUseDevFlags();
435
462
  if (useDevFlags) {
@@ -439,6 +466,8 @@ export async function trackClick(adId: string): Promise<void> {
439
466
 
440
467
  const response = await fetch(trackingUrl, {
441
468
  method: 'POST',
469
+ mode: 'cors', // Explicitly enable CORS
470
+ credentials: 'omit', // Don't send cookies
442
471
  headers: {
443
472
  'Content-Type': 'application/json',
444
473
  'Accept': 'application/json',
@@ -459,7 +488,14 @@ export async function trackClick(adId: string): Promise<void> {
459
488
  console.log(`[DEV] Click tracking skipped for ad: ${adId}`);
460
489
  }
461
490
  } catch (error) {
462
- console.error('Error tracking click:', error);
491
+ // Handle CORS errors gracefully (tracking failures shouldn't break the app)
492
+ if (error instanceof TypeError && (error.message.includes('CORS') || error.message.includes('Failed to fetch'))) {
493
+ // This is expected until the server configures CORS for /api/ads/track endpoint
494
+ // The ad still works correctly, click tracking just won't work until server-side CORS is fixed
495
+ console.debug(`[AdBanner] Tracking click failed (CORS): The /api/ads/track endpoint needs CORS headers configured on the server. Ad still works correctly.`);
496
+ } else {
497
+ console.error('Error tracking click:', error);
498
+ }
463
499
  // Don't throw - tracking failures shouldn't break the app
464
500
  }
465
501
  }