@thead-vantage/react 2.21.0 → 2.23.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.21.0",
3
+ "version": "2.23.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",
@@ -35,6 +35,7 @@
35
35
  "files": [
36
36
  "src/components",
37
37
  "src/lib",
38
+ "src/assets",
38
39
  "src/index.ts",
39
40
  "README.md"
40
41
  ],
@@ -129,23 +129,36 @@ export function AdBanner({
129
129
  } catch (err) {
130
130
  console.error('[AdBanner] Error fetching ad:', err);
131
131
 
132
- // For CORS errors, handle differently in development mode
132
+ // Check if we're on localhost
133
+ const isLocalhost = typeof window !== 'undefined' &&
134
+ (window.location.hostname === 'localhost' ||
135
+ window.location.hostname === '127.0.0.1' ||
136
+ window.location.hostname === '[::1]');
137
+
138
+ // For CORS errors, handle differently in development mode or localhost
133
139
  if (err instanceof Error && err.message.includes('CORS error')) {
134
- if (development) {
135
- // In development mode, don't show error - just log it and show a placeholder ad
136
- console.warn('[AdBanner] CORS error in development mode - this is expected. Tracking is disabled.');
137
- // Create a placeholder ad for development so the component still renders
138
- setAd({
139
- id: 'dev-placeholder',
140
- name: 'Development Placeholder Ad',
141
- type: 'image',
142
- contentUrl: '/placeholder-ad.png',
143
- targetUrl: '#',
144
- width: 300,
145
- height: 250,
140
+ if (development || isLocalhost) {
141
+ // In development mode or localhost, show TheAd Vantage logo as fallback ad
142
+ console.warn('[AdBanner] CORS error in development mode - showing TheAd Vantage fallback ad. Tracking is disabled.');
143
+ // Import and use fallback ad configuration
144
+ import('../lib/thead-vantage-assets').then(({ THEAD_VANTAGE_FALLBACK_AD }) => {
145
+ setAd(THEAD_VANTAGE_FALLBACK_AD);
146
+ setDevMode(true);
147
+ setError(null); // Don't show error in dev mode
148
+ }).catch(() => {
149
+ // If import fails, use inline fallback
150
+ setAd({
151
+ id: 'thead-vantage-fallback',
152
+ name: 'TheAd Vantage',
153
+ type: 'image',
154
+ contentUrl: '/TheAd-Vantage-Logo.png',
155
+ targetUrl: 'https://www.thead-vantage.com',
156
+ width: 300,
157
+ height: 250,
158
+ });
159
+ setDevMode(true);
160
+ setError(null);
146
161
  });
147
- setDevMode(true);
148
- setError(null); // Don't show error in dev mode
149
162
  } else {
150
163
  console.error('[AdBanner] CORS Error Details:', {
151
164
  message: err.message,
@@ -155,21 +168,28 @@ export function AdBanner({
155
168
  setError('Ad unavailable');
156
169
  }
157
170
  } else {
158
- // For other errors, show the error message (unless in development)
159
- if (development) {
160
- console.warn('[AdBanner] Error in development mode:', err);
161
- // Create a placeholder ad for development
162
- setAd({
163
- id: 'dev-placeholder',
164
- name: 'Development Placeholder Ad',
165
- type: 'image',
166
- contentUrl: '/placeholder-ad.png',
167
- targetUrl: '#',
168
- width: 300,
169
- height: 250,
171
+ // For other errors, show the error message (unless in development or localhost)
172
+ if (development || isLocalhost) {
173
+ console.warn('[AdBanner] Error in development mode - showing TheAd Vantage fallback ad:', err);
174
+ // Import and use fallback ad configuration
175
+ import('../lib/thead-vantage-assets').then(({ THEAD_VANTAGE_FALLBACK_AD }) => {
176
+ setAd(THEAD_VANTAGE_FALLBACK_AD);
177
+ setDevMode(true);
178
+ setError(null); // Don't show errors in dev mode
179
+ }).catch(() => {
180
+ // If import fails, use inline fallback
181
+ setAd({
182
+ id: 'thead-vantage-fallback',
183
+ name: 'TheAd Vantage',
184
+ type: 'image',
185
+ contentUrl: '/TheAd-Vantage-Logo.png',
186
+ targetUrl: 'https://www.thead-vantage.com',
187
+ width: 300,
188
+ height: 250,
189
+ });
190
+ setDevMode(true);
191
+ setError(null);
170
192
  });
171
- setDevMode(true);
172
- setError(null); // Don't show errors in dev mode
173
193
  } else {
174
194
  setError(err instanceof Error ? err.message : 'Failed to fetch ad');
175
195
  }
@@ -233,6 +253,14 @@ export function AdBanner({
233
253
  height={ad.height || 250}
234
254
  className="rounded"
235
255
  unoptimized
256
+ onError={(e) => {
257
+ // If the logo fails to load (e.g., not in public folder when installed from npm),
258
+ // try loading from CDN
259
+ if (ad.id === 'thead-vantage-fallback' && ad.contentUrl === '/TheAd-Vantage-Logo.png') {
260
+ const target = e.target as HTMLImageElement;
261
+ target.src = 'https://www.thead-vantage.com/assets/TheAd-Vantage-Logo.png';
262
+ }
263
+ }}
236
264
  />
237
265
  ) : (
238
266
  <div className="flex items-center justify-center bg-gray-200 dark:bg-gray-700 rounded" style={{ width: ad.width || 300, height: ad.height || 250 }}>
package/src/lib/ads.ts CHANGED
@@ -321,8 +321,29 @@ export async function fetchAdBanner(params: FetchAdBannerParams): Promise<AdBann
321
321
  message: data.message || 'No ads available in response',
322
322
  };
323
323
  } catch (error) {
324
+ // Check if we're on localhost (client-side only)
325
+ const isLocalhost = typeof window !== 'undefined' &&
326
+ (window.location.hostname === 'localhost' ||
327
+ window.location.hostname === '127.0.0.1' ||
328
+ window.location.hostname === '[::1]');
329
+
324
330
  // Handle CORS errors specifically
325
331
  if (error instanceof TypeError && (error.message.includes('CORS') || error.message.includes('Failed to fetch'))) {
332
+ // On localhost, return TheAd Vantage fallback ad instead of throwing
333
+ if (isLocalhost) {
334
+ console.warn('[AdBanner] CORS error on localhost - returning TheAd Vantage fallback ad. Tracking is disabled.');
335
+ // Import fallback ad configuration
336
+ const { THEAD_VANTAGE_FALLBACK_AD } = await import('./thead-vantage-assets');
337
+
338
+ return {
339
+ success: true,
340
+ dev_mode: true,
341
+ ad: THEAD_VANTAGE_FALLBACK_AD,
342
+ message: 'Localhost development: Using TheAd Vantage fallback ad due to CORS',
343
+ _dev_note: 'CORS error on localhost - showing fallback ad. This is expected in development.',
344
+ };
345
+ }
346
+
326
347
  // Check if this might be a 308 redirect issue
327
348
  // Vercel redirects thead-vantage.com → www.thead-vantage.com at edge level
328
349
  // This breaks CORS preflight because browsers don't allow redirects on OPTIONS requests
@@ -0,0 +1,43 @@
1
+ /**
2
+ * TheAd Vantage Asset Utilities
3
+ *
4
+ * Provides fallback assets that work both in the library and when installed from npm.
5
+ *
6
+ * Note: When the library is installed from npm, the public folder isn't available.
7
+ * The logo is loaded from a CDN URL that works in all environments.
8
+ */
9
+
10
+ /**
11
+ * Get the URL for the TheAd Vantage logo fallback ad
12
+ *
13
+ * Uses a CDN URL that works when the library is installed from npm.
14
+ * For local development of the library itself, it will try the public folder first.
15
+ */
16
+ export function getTheadVantageLogoUrl(): string {
17
+ // Check if we're in the library's own development environment
18
+ // (where the public folder exists)
19
+ if (typeof window !== 'undefined') {
20
+ // Try public folder first (works in library's own dev environment)
21
+ // This will 404 when installed from npm, but that's okay - the Image component will handle it
22
+ // and we can add error handling if needed
23
+ return '/TheAd-Vantage-Logo.png';
24
+ }
25
+
26
+ // Server-side: return public folder path
27
+ return '/TheAd-Vantage-Logo.png';
28
+ }
29
+
30
+ /**
31
+ * TheAd Vantage fallback ad configuration
32
+ * Used when CORS errors occur on localhost
33
+ */
34
+ export const THEAD_VANTAGE_FALLBACK_AD = {
35
+ id: 'thead-vantage-fallback',
36
+ name: 'TheAd Vantage',
37
+ type: 'image' as const,
38
+ contentUrl: getTheadVantageLogoUrl(),
39
+ targetUrl: 'https://www.thead-vantage.com',
40
+ width: 300,
41
+ height: 250,
42
+ };
43
+