@thead-vantage/react 2.6.0 → 2.7.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thead-vantage/react",
3
- "version": "2.6.0",
3
+ "version": "2.7.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
@@ -264,14 +264,34 @@ export async function fetchAdBanner(params: FetchAdBannerParams): Promise<AdBann
264
264
 
265
265
  /**
266
266
  * Track an ad impression (when ad is viewed)
267
- * In development mode, this is a no-op (handled by API route)
267
+ * Sends tracking directly to TheAd Vantage API (or skips in dev mode)
268
268
  */
269
269
  export async function trackImpression(adId: string): Promise<void> {
270
270
  try {
271
- const response = await fetch('/api/ads', {
271
+ // Get the API base URL to determine where to send tracking
272
+ const apiBaseUrl = getApiBaseUrl();
273
+
274
+ // Build tracking URL - remove /api/ads if present, then append /api/ads/track
275
+ let trackingUrl = apiBaseUrl.trim();
276
+ if (trackingUrl.endsWith('/api/ads')) {
277
+ trackingUrl = trackingUrl.replace('/api/ads', '/api/ads/track');
278
+ } else {
279
+ // Remove trailing slash if present
280
+ trackingUrl = trackingUrl.replace(/\/$/, '') + '/api/ads/track';
281
+ }
282
+
283
+ // Check if we should skip tracking (dev mode)
284
+ const useDevFlags = shouldUseDevFlags();
285
+ if (useDevFlags) {
286
+ console.log(`[DEV] Impression tracking skipped for ad: ${adId}`);
287
+ return;
288
+ }
289
+
290
+ const response = await fetch(trackingUrl, {
272
291
  method: 'POST',
273
292
  headers: {
274
293
  'Content-Type': 'application/json',
294
+ 'Accept': 'application/json',
275
295
  },
276
296
  body: JSON.stringify({
277
297
  action: 'impression',
@@ -279,6 +299,11 @@ export async function trackImpression(adId: string): Promise<void> {
279
299
  }),
280
300
  });
281
301
 
302
+ if (!response.ok) {
303
+ console.warn(`[AdBanner] Tracking impression failed: ${response.status} ${response.statusText}`);
304
+ return;
305
+ }
306
+
282
307
  const data = await response.json();
283
308
  if (data.dev_mode) {
284
309
  console.log(`[DEV] Impression tracking skipped for ad: ${adId}`);
@@ -291,14 +316,34 @@ export async function trackImpression(adId: string): Promise<void> {
291
316
 
292
317
  /**
293
318
  * Track an ad click
294
- * In development mode, this is a no-op (handled by API route)
319
+ * Sends tracking directly to TheAd Vantage API (or skips in dev mode)
295
320
  */
296
321
  export async function trackClick(adId: string): Promise<void> {
297
322
  try {
298
- const response = await fetch('/api/ads', {
323
+ // Get the API base URL to determine where to send tracking
324
+ const apiBaseUrl = getApiBaseUrl();
325
+
326
+ // Build tracking URL - remove /api/ads if present, then append /api/ads/track
327
+ let trackingUrl = apiBaseUrl.trim();
328
+ if (trackingUrl.endsWith('/api/ads')) {
329
+ trackingUrl = trackingUrl.replace('/api/ads', '/api/ads/track');
330
+ } else {
331
+ // Remove trailing slash if present
332
+ trackingUrl = trackingUrl.replace(/\/$/, '') + '/api/ads/track';
333
+ }
334
+
335
+ // Check if we should skip tracking (dev mode)
336
+ const useDevFlags = shouldUseDevFlags();
337
+ if (useDevFlags) {
338
+ console.log(`[DEV] Click tracking skipped for ad: ${adId}`);
339
+ return;
340
+ }
341
+
342
+ const response = await fetch(trackingUrl, {
299
343
  method: 'POST',
300
344
  headers: {
301
345
  'Content-Type': 'application/json',
346
+ 'Accept': 'application/json',
302
347
  },
303
348
  body: JSON.stringify({
304
349
  action: 'click',
@@ -306,6 +351,11 @@ export async function trackClick(adId: string): Promise<void> {
306
351
  }),
307
352
  });
308
353
 
354
+ if (!response.ok) {
355
+ console.warn(`[AdBanner] Tracking click failed: ${response.status} ${response.statusText}`);
356
+ return;
357
+ }
358
+
309
359
  const data = await response.json();
310
360
  if (data.dev_mode) {
311
361
  console.log(`[DEV] Click tracking skipped for ad: ${adId}`);
@@ -31,47 +31,78 @@ function isLocalhost(): boolean {
31
31
  * 5. Production mode (default) → https://thead-vantage.com (full tracking)
32
32
  */
33
33
  export function getApiBaseUrl(explicitApiUrl?: string): string {
34
+ let selectedUrl: string | undefined;
35
+ let reason: string | undefined;
36
+
34
37
  // Priority 1: Explicit API URL override (highest priority)
35
38
  if (explicitApiUrl) {
36
- return explicitApiUrl;
39
+ selectedUrl = explicitApiUrl;
40
+ reason = 'explicit API URL parameter';
37
41
  }
38
-
39
42
  // Priority 2: Environment variable for custom API URL
40
43
  // This allows platform developers to point to their own platform
41
- if (typeof window !== 'undefined') {
44
+ else if (typeof window !== 'undefined') {
42
45
  // Check runtime config first (for browser contexts)
43
46
  const runtimeUrl = (window as any).__THEAD_VANTAGE_API_URL__;
44
- if (runtimeUrl) {
45
- return runtimeUrl;
47
+ if (runtimeUrl && typeof runtimeUrl === 'string' && runtimeUrl.trim()) {
48
+ // Validate that it's not pointing to the current page's origin (would be wrong)
49
+ const currentOrigin = window.location.origin;
50
+ if (!runtimeUrl.startsWith(currentOrigin)) {
51
+ selectedUrl = runtimeUrl;
52
+ reason = 'runtime config (window.__THEAD_VANTAGE_API_URL__)';
53
+ } else {
54
+ console.warn('[TheAd Vantage] Runtime API URL points to current origin, ignoring:', runtimeUrl);
55
+ }
46
56
  }
47
57
  }
48
58
 
49
59
  // Check environment variable (works in both server and client)
50
- const customUrl = process.env.NEXT_PUBLIC_THEAD_VANTAGE_API_URL;
51
- if (customUrl) {
52
- return customUrl;
60
+ if (!selectedUrl) {
61
+ const customUrl = process.env.NEXT_PUBLIC_THEAD_VANTAGE_API_URL;
62
+ if (customUrl && customUrl.trim()) {
63
+ // Validate that it's not pointing to localhost without being TheAd Vantage dev mode
64
+ if (customUrl.includes('localhost') && !customUrl.includes('localhost:3001')) {
65
+ console.warn('[TheAd Vantage] Custom API URL points to localhost (not :3001), this may be incorrect:', customUrl);
66
+ }
67
+ selectedUrl = customUrl;
68
+ reason = 'NEXT_PUBLIC_THEAD_VANTAGE_API_URL environment variable';
69
+ }
53
70
  }
54
71
 
55
72
  // Priority 3: TheAd Vantage dev mode
56
73
  // Only for TheAd Vantage developers testing locally with localhost:3001
57
- const isTheadVantageDevMode = typeof window !== 'undefined'
58
- ? (window as any).__THEAD_VANTAGE_DEV_MODE__ === true ||
59
- process.env.NEXT_PUBLIC_THEAD_VANTAGE_DEV_MODE === 'true'
60
- : process.env.NEXT_PUBLIC_THEAD_VANTAGE_DEV_MODE === 'true';
61
-
62
- if (isTheadVantageDevMode) {
63
- return 'http://localhost:3001/api/ads';
74
+ if (!selectedUrl) {
75
+ const isTheadVantageDevMode = typeof window !== 'undefined'
76
+ ? (window as any).__THEAD_VANTAGE_DEV_MODE__ === true ||
77
+ process.env.NEXT_PUBLIC_THEAD_VANTAGE_DEV_MODE === 'true'
78
+ : process.env.NEXT_PUBLIC_THEAD_VANTAGE_DEV_MODE === 'true';
79
+
80
+ if (isTheadVantageDevMode) {
81
+ selectedUrl = 'http://localhost:3001/api/ads';
82
+ reason = 'TheAd Vantage dev mode (NEXT_PUBLIC_THEAD_VANTAGE_DEV_MODE=true)';
83
+ }
64
84
  }
65
85
 
66
86
  // Priority 4: Localhost development (platform developers on localhost)
67
87
  // Use production API but will add dev flags to prevent tracking
68
- if (isLocalhost()) {
69
- return 'https://thead-vantage.com/api/ads';
88
+ if (!selectedUrl && isLocalhost()) {
89
+ selectedUrl = 'https://thead-vantage.com/api/ads';
90
+ reason = 'localhost detection (production API with dev flags)';
70
91
  }
71
92
 
72
93
  // Priority 5: Production mode (default)
73
94
  // Platform developers use this by default in production
74
- return 'https://thead-vantage.com/api/ads';
95
+ if (!selectedUrl) {
96
+ selectedUrl = 'https://thead-vantage.com/api/ads';
97
+ reason = 'production mode (default)';
98
+ }
99
+
100
+ // Log which URL was selected (helpful for debugging)
101
+ if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') {
102
+ console.log(`[TheAd Vantage] API Base URL selected: ${selectedUrl} (reason: ${reason})`);
103
+ }
104
+
105
+ return selectedUrl;
75
106
  }
76
107
 
77
108
  /**