@adstage/web-sdk 1.3.4 → 2.0.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 (60) hide show
  1. package/README.md +539 -34
  2. package/dist/index.cjs.js +753 -509
  3. package/dist/index.d.ts +286 -97
  4. package/dist/index.esm.js +737 -485
  5. package/dist/index.standalone.js +737 -485
  6. package/package.json +12 -13
  7. package/src/constants/endpoints.ts +93 -0
  8. package/src/core/AdStage.ts +128 -0
  9. package/src/index.ts +14 -432
  10. package/src/managers/{slider-manager.ts → carousel-slider-manager.ts} +9 -8
  11. package/src/managers/event-tracker.ts +2 -4
  12. package/src/managers/{fade-slider-manager.ts → text-transition-manager.ts} +7 -7
  13. package/src/modules/ads/AdsModule.ts +525 -0
  14. package/src/modules/config/ConfigModule.ts +124 -0
  15. package/src/modules/events/EventsModule.ts +106 -0
  16. package/src/types/config.ts +74 -3
  17. package/src/types/index.ts +2 -1
  18. package/src/utils/api-headers.ts +52 -0
  19. package/src/utils/dom-utils.ts +1 -1
  20. package/examples/README.md +0 -33
  21. package/examples/banner-ads.html +0 -512
  22. package/examples/index.html +0 -338
  23. package/examples/native-ads.html +0 -634
  24. package/examples/react-app/README.md +0 -70
  25. package/examples/react-app/index.html +0 -13
  26. package/examples/react-app/package-lock.json +0 -3042
  27. package/examples/react-app/package.json +0 -26
  28. package/examples/react-app/pnpm-lock.yaml +0 -1857
  29. package/examples/react-app/public/index.standalone.js +0 -2331
  30. package/examples/react-app/src/App.tsx +0 -226
  31. package/examples/react-app/src/index.css +0 -37
  32. package/examples/react-app/src/main.tsx +0 -10
  33. package/examples/react-app/tsconfig.json +0 -25
  34. package/examples/react-app/tsconfig.node.json +0 -10
  35. package/examples/react-app/vite.config.ts +0 -15
  36. package/examples/react-nextjs/app/globals.css +0 -200
  37. package/examples/react-nextjs/app/layout.tsx +0 -27
  38. package/examples/react-nextjs/app/page.tsx +0 -258
  39. package/examples/react-nextjs/next.config.js +0 -9
  40. package/examples/react-nextjs/package.json +0 -22
  41. package/examples/react-nextjs/pnpm-lock.yaml +0 -343
  42. package/examples/react-nextjs/tsconfig.json +0 -34
  43. package/examples/text-ads.html +0 -597
  44. package/examples/video-ads.html +0 -739
  45. package/src/react/components/AdErrorBoundary.tsx +0 -75
  46. package/src/react/components/AdSlot.tsx +0 -144
  47. package/src/react/components/BannerAd.tsx +0 -24
  48. package/src/react/components/InterstitialAd.tsx +0 -24
  49. package/src/react/components/NativeAd.tsx +0 -24
  50. package/src/react/components/TextAd.tsx +0 -24
  51. package/src/react/components/VideoAd.tsx +0 -24
  52. package/src/react/components/index.ts +0 -8
  53. package/src/react/hooks/index.ts +0 -4
  54. package/src/react/hooks/useAdSlot.ts +0 -83
  55. package/src/react/hooks/useAdStage.ts +0 -14
  56. package/src/react/hooks/useAdTracking.ts +0 -61
  57. package/src/react/index.ts +0 -4
  58. package/src/react/providers/AdStageProvider.tsx +0 -86
  59. package/src/react/providers/index.ts +0 -2
  60. package/src/utils/sdk-standalone.ts +0 -155
@@ -1,634 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="ko">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>네이티브 광고 예제 - AdStage SDK</title>
7
- <style>
8
- * {
9
- box-sizing: border-box;
10
- margin: 0;
11
- padding: 0;
12
- }
13
-
14
- body {
15
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
16
- line-height: 1.6;
17
- color: #333;
18
- background: #f8f9fa;
19
- padding: 20px;
20
- }
21
-
22
- .container {
23
- max-width: 1200px;
24
- margin: 0 auto;
25
- background: white;
26
- border-radius: 12px;
27
- box-shadow: 0 4px 12px rgba(0,0,0,0.1);
28
- overflow: hidden;
29
- }
30
-
31
- .header {
32
- background: linear-gradient(135deg, #6f42c1, #e83e8c);
33
- color: white;
34
- padding: 30px;
35
- text-align: center;
36
- }
37
-
38
- .header h1 {
39
- font-size: 2rem;
40
- margin-bottom: 10px;
41
- }
42
-
43
- .nav {
44
- background: #f8f9fa;
45
- padding: 15px 30px;
46
- border-bottom: 1px solid #dee2e6;
47
- }
48
-
49
- .back-link {
50
- color: #6f42c1;
51
- text-decoration: none;
52
- font-weight: 500;
53
- }
54
-
55
- .content {
56
- padding: 30px;
57
- }
58
-
59
- .section {
60
- margin-bottom: 40px;
61
- }
62
-
63
- .section h2 {
64
- color: #495057;
65
- margin-bottom: 20px;
66
- padding-bottom: 10px;
67
- border-bottom: 2px solid #6f42c1;
68
- }
69
-
70
- .feed-container {
71
- display: grid;
72
- grid-template-columns: 1fr;
73
- gap: 20px;
74
- max-width: 600px;
75
- margin: 0 auto;
76
- }
77
-
78
- .feed-item {
79
- background: white;
80
- border: 1px solid #dee2e6;
81
- border-radius: 12px;
82
- padding: 20px;
83
- box-shadow: 0 2px 8px rgba(0,0,0,0.05);
84
- transition: all 0.3s ease;
85
- }
86
-
87
- .feed-item:hover {
88
- box-shadow: 0 4px 16px rgba(0,0,0,0.1);
89
- transform: translateY(-2px);
90
- }
91
-
92
- .feed-item.sponsored {
93
- border-color: #6f42c1;
94
- background: linear-gradient(135deg, #fff, #f8f6ff);
95
- }
96
-
97
- .sponsored-label {
98
- background: #6f42c1;
99
- color: white;
100
- font-size: 0.7rem;
101
- padding: 3px 8px;
102
- border-radius: 12px;
103
- margin-bottom: 12px;
104
- display: inline-block;
105
- }
106
-
107
- .feed-header {
108
- display: flex;
109
- align-items: center;
110
- margin-bottom: 15px;
111
- }
112
-
113
- .feed-avatar {
114
- width: 40px;
115
- height: 40px;
116
- border-radius: 50%;
117
- background: linear-gradient(45deg, #6f42c1, #e83e8c);
118
- display: flex;
119
- align-items: center;
120
- justify-content: center;
121
- color: white;
122
- font-weight: bold;
123
- margin-right: 12px;
124
- }
125
-
126
- .feed-meta {
127
- flex: 1;
128
- }
129
-
130
- .feed-author {
131
- font-weight: 600;
132
- color: #495057;
133
- font-size: 0.95rem;
134
- }
135
-
136
- .feed-time {
137
- color: #6c757d;
138
- font-size: 0.8rem;
139
- }
140
-
141
- .feed-content {
142
- margin-bottom: 15px;
143
- }
144
-
145
- .feed-title {
146
- font-size: 1.1rem;
147
- font-weight: 600;
148
- color: #495057;
149
- margin-bottom: 8px;
150
- cursor: pointer;
151
- }
152
-
153
- .feed-title:hover {
154
- color: #6f42c1;
155
- }
156
-
157
- .feed-description {
158
- color: #6c757d;
159
- font-size: 0.95rem;
160
- line-height: 1.5;
161
- }
162
-
163
- .feed-image {
164
- width: 100%;
165
- height: 200px;
166
- background: linear-gradient(45deg, #f8f9fa, #e9ecef);
167
- border-radius: 8px;
168
- margin: 15px 0;
169
- display: flex;
170
- align-items: center;
171
- justify-content: center;
172
- color: #6c757d;
173
- font-size: 0.9rem;
174
- border: 2px dashed #dee2e6;
175
- }
176
-
177
- .feed-actions {
178
- display: flex;
179
- justify-content: space-between;
180
- align-items: center;
181
- padding-top: 15px;
182
- border-top: 1px solid #e9ecef;
183
- }
184
-
185
- .feed-cta {
186
- background: #6f42c1;
187
- color: white;
188
- padding: 8px 16px;
189
- border: none;
190
- border-radius: 20px;
191
- cursor: pointer;
192
- font-size: 0.9rem;
193
- transition: background 0.3s ease;
194
- }
195
-
196
- .feed-cta:hover {
197
- background: #5a2d91;
198
- }
199
-
200
- .feed-stats {
201
- color: #6c757d;
202
- font-size: 0.85rem;
203
- }
204
-
205
- .native-ad-slot {
206
- position: relative;
207
- }
208
-
209
- .native-ad-slot.loading::before {
210
- content: "🔄 네이티브 광고 로딩 중...";
211
- position: absolute;
212
- top: 50%;
213
- left: 50%;
214
- transform: translate(-50%, -50%);
215
- color: #6c757d;
216
- font-size: 0.9rem;
217
- z-index: 10;
218
- }
219
-
220
- .native-ad-slot.loading .feed-item {
221
- opacity: 0.3;
222
- }
223
-
224
- .card-grid {
225
- display: grid;
226
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
227
- gap: 20px;
228
- margin-bottom: 30px;
229
- }
230
-
231
- .card-item {
232
- background: white;
233
- border: 2px solid #e9ecef;
234
- border-radius: 12px;
235
- overflow: hidden;
236
- transition: all 0.3s ease;
237
- }
238
-
239
- .card-item:hover {
240
- border-color: #6f42c1;
241
- box-shadow: 0 4px 12px rgba(111, 66, 193, 0.15);
242
- }
243
-
244
- .card-image {
245
- width: 100%;
246
- height: 160px;
247
- background: linear-gradient(45deg, #6f42c1, #e83e8c);
248
- display: flex;
249
- align-items: center;
250
- justify-content: center;
251
- color: white;
252
- font-size: 1.2rem;
253
- }
254
-
255
- .card-content {
256
- padding: 20px;
257
- }
258
-
259
- .card-title {
260
- font-size: 1.1rem;
261
- font-weight: 600;
262
- color: #495057;
263
- margin-bottom: 10px;
264
- }
265
-
266
- .card-description {
267
- color: #6c757d;
268
- font-size: 0.9rem;
269
- line-height: 1.5;
270
- margin-bottom: 15px;
271
- }
272
-
273
- .card-footer {
274
- display: flex;
275
- justify-content: space-between;
276
- align-items: center;
277
- }
278
-
279
- .controls {
280
- display: flex;
281
- gap: 10px;
282
- margin-top: 20px;
283
- flex-wrap: wrap;
284
- }
285
-
286
- .btn {
287
- padding: 8px 16px;
288
- border: none;
289
- border-radius: 6px;
290
- background: #6f42c1;
291
- color: white;
292
- cursor: pointer;
293
- font-size: 0.9rem;
294
- transition: background 0.3s ease;
295
- }
296
-
297
- .btn:hover {
298
- background: #5a2d91;
299
- }
300
-
301
- .btn.secondary {
302
- background: #6c757d;
303
- }
304
-
305
- .status {
306
- margin-top: 30px;
307
- padding: 20px;
308
- background: #e2d9f3;
309
- border-left: 4px solid #6f42c1;
310
- border-radius: 4px;
311
- }
312
-
313
- .log {
314
- background: #f8f9fa;
315
- border: 1px solid #dee2e6;
316
- border-radius: 6px;
317
- padding: 15px;
318
- max-height: 200px;
319
- overflow-y: auto;
320
- font-family: monospace;
321
- font-size: 0.8rem;
322
- margin-top: 15px;
323
- }
324
-
325
- .log-entry {
326
- margin-bottom: 5px;
327
- padding: 2px 5px;
328
- border-radius: 3px;
329
- }
330
-
331
- .log-entry.info {
332
- background: #d4edda;
333
- color: #155724;
334
- }
335
- </style>
336
- </head>
337
- <body>
338
- <div class="container">
339
- <div class="header">
340
- <h1>🎯 네이티브 광고 예제</h1>
341
- <p>콘텐츠와 자연스럽게 어울리는 광고 형태</p>
342
- </div>
343
-
344
- <div class="nav">
345
- <a href="index.html" class="back-link">← 메인 페이지로 돌아가기</a>
346
- </div>
347
-
348
- <div class="content">
349
- <div class="section">
350
- <h2>📱 소셜 피드 형태 네이티브 광고</h2>
351
- <p style="margin-bottom: 20px; color: #6c757d;">일반 피드 콘텐츠 사이에 자연스럽게 삽입되는 광고</p>
352
-
353
- <div class="feed-container">
354
- <!-- 일반 피드 아이템 -->
355
- <div class="feed-item">
356
- <div class="feed-header">
357
- <div class="feed-avatar">👤</div>
358
- <div class="feed-meta">
359
- <div class="feed-author">김개발자</div>
360
- <div class="feed-time">2시간 전</div>
361
- </div>
362
- </div>
363
- <div class="feed-content">
364
- <div class="feed-title">새로운 프로젝트 시작!</div>
365
- <div class="feed-description">React와 TypeScript로 멋진 웹 애플리케이션을 개발하고 있습니다. 진행 상황을 공유해보겠습니다.</div>
366
- </div>
367
- <div class="feed-actions">
368
- <div class="feed-stats">좋아요 24 • 댓글 5</div>
369
- </div>
370
- </div>
371
-
372
- <!-- 네이티브 광고 슬롯 1 -->
373
- <div class="native-ad-slot loading"
374
- id="feed-native-1"
375
- adstage="feed-native-1"
376
- ad-type="NATIVE">
377
- <div class="feed-item sponsored">
378
- <span class="sponsored-label">스폰서</span>
379
- <div class="feed-header">
380
- <div class="feed-avatar">🚀</div>
381
- <div class="feed-meta">
382
- <div class="feed-author">TechStartup</div>
383
- <div class="feed-time">프로모션</div>
384
- </div>
385
- </div>
386
- <div class="feed-content">
387
- <div class="feed-title">혁신적인 개발 도구 출시!</div>
388
- <div class="feed-description">개발자의 생산성을 2배 향상시키는 새로운 IDE 플러그인입니다. 코드 자동완성과 실시간 오류 검사 기능이 포함되어 있습니다.</div>
389
- <div class="feed-image">📊 개발 도구 스크린샷</div>
390
- </div>
391
- <div class="feed-actions">
392
- <div class="feed-stats">개발자들이 추천하는 도구</div>
393
- <button class="feed-cta">무료 체험하기</button>
394
- </div>
395
- </div>
396
- </div>
397
-
398
- <!-- 일반 피드 아이템 -->
399
- <div class="feed-item">
400
- <div class="feed-header">
401
- <div class="feed-avatar">🎨</div>
402
- <div class="feed-meta">
403
- <div class="feed-author">디자이너 박</div>
404
- <div class="feed-time">4시간 전</div>
405
- </div>
406
- </div>
407
- <div class="feed-content">
408
- <div class="feed-title">UI/UX 디자인 트렌드 2024</div>
409
- <div class="feed-description">올해 주목해야 할 디자인 트렌드들을 정리해보았습니다. 미니멀리즘이 계속 인기를 끌고 있네요.</div>
410
- </div>
411
- <div class="feed-actions">
412
- <div class="feed-stats">좋아요 56 • 댓글 12</div>
413
- </div>
414
- </div>
415
-
416
- <!-- 네이티브 광고 슬롯 2 -->
417
- <div class="native-ad-slot loading"
418
- id="feed-native-2"
419
- adstage="feed-native-2"
420
- ad-type="NATIVE">
421
- <div class="feed-item sponsored">
422
- <span class="sponsored-label">스폰서</span>
423
- <div class="feed-header">
424
- <div class="feed-avatar">📚</div>
425
- <div class="feed-meta">
426
- <div class="feed-author">온라인 학습플랫폼</div>
427
- <div class="feed-time">프로모션</div>
428
- </div>
429
- </div>
430
- <div class="feed-content">
431
- <div class="feed-title">프로그래밍 마스터 과정</div>
432
- <div class="feed-description">초보자부터 전문가까지, 단계별로 배우는 완전한 프로그래밍 커리큘럼. 실습 프로젝트와 멘토링이 포함됩니다.</div>
433
- <div class="feed-image">🎓 온라인 강의 이미지</div>
434
- </div>
435
- <div class="feed-actions">
436
- <div class="feed-stats">수강생 1,000+ • 평점 4.9</div>
437
- <button class="feed-cta">강의 보기</button>
438
- </div>
439
- </div>
440
- </div>
441
- </div>
442
- </div>
443
-
444
- <div class="section">
445
- <h2>🃏 카드 형태 네이티브 광고</h2>
446
- <p style="margin-bottom: 20px; color: #6c757d;">뉴스나 블로그 형태의 카드 레이아웃에 삽입되는 광고</p>
447
-
448
- <div class="card-grid">
449
- <!-- 네이티브 광고 카드 1 -->
450
- <div class="card-item native-ad-slot loading"
451
- id="card-native-1"
452
- adstage="card-native-1"
453
- ad-type="NATIVE">
454
- <div class="card-image">💼 비즈니스</div>
455
- <div class="card-content">
456
- <span class="sponsored-label">스폰서</span>
457
- <div class="card-title">스타트업 성공의 비밀</div>
458
- <div class="card-description">실리콘밸리 멘토들이 알려주는 스타트업 성공 전략. 실제 사례와 노하우를 바탕으로 한 실용적인 가이드입니다.</div>
459
- <div class="card-footer">
460
- <span style="color: #6c757d; font-size: 0.8rem;">비즈니스 가이드</span>
461
- <button class="feed-cta">자세히 보기</button>
462
- </div>
463
- </div>
464
- </div>
465
-
466
- <!-- 네이티브 광고 카드 2 -->
467
- <div class="card-item native-ad-slot loading"
468
- id="card-native-2"
469
- adstage="card-native-2"
470
- ad-type="NATIVE">
471
- <div class="card-image">🎯 마케팅</div>
472
- <div class="card-content">
473
- <span class="sponsored-label">스폰서</span>
474
- <div class="card-title">디지털 마케팅 완벽 가이드</div>
475
- <div class="card-description">SNS 마케팅부터 퍼포먼스 마케팅까지, 디지털 시대의 마케팅 전략을 한 번에 배워보세요.</div>
476
- <div class="card-footer">
477
- <span style="color: #6c757d; font-size: 0.8rem;">마케팅 교육</span>
478
- <button class="feed-cta">신청하기</button>
479
- </div>
480
- </div>
481
- </div>
482
-
483
- <!-- 네이티브 광고 카드 3 -->
484
- <div class="card-item native-ad-slot loading"
485
- id="card-native-3"
486
- adstage="card-native-3"
487
- ad-type="NATIVE">
488
- <div class="card-image">🏠 부동산</div>
489
- <div class="card-content">
490
- <span class="sponsored-label">스폰서</span>
491
- <div class="card-title">스마트 홈 솔루션</div>
492
- <div class="card-description">IoT 기술로 더 편리하고 안전한 집을 만들어보세요. 에너지 절약 효과까지 누릴 수 있습니다.</div>
493
- <div class="card-footer">
494
- <span style="color: #6c757d; font-size: 0.8rem;">스마트홈</span>
495
- <button class="feed-cta">체험하기</button>
496
- </div>
497
- </div>
498
- </div>
499
- </div>
500
- </div>
501
-
502
- <div class="section">
503
- <h2>⚡ 광고 제어</h2>
504
- <div class="controls">
505
- <button class="btn" onclick="refreshAllNativeAds()">🔄 네이티브 광고 새로고침</button>
506
- <button class="btn secondary" onclick="hideAllAds()">👁️ 모든 광고 숨기기</button>
507
- <button class="btn" onclick="showAllAds()">👀 모든 광고 보이기</button>
508
- <button class="btn secondary" onclick="clearLog()">🧹 로그 지우기</button>
509
- </div>
510
- </div>
511
-
512
- <div class="status" id="status">
513
- SDK 초기화 중...
514
- </div>
515
-
516
- <div class="log" id="log">
517
- <div class="log-entry info">네이티브 광고 페이지 로드 시작...</div>
518
- </div>
519
- </div>
520
- </div>
521
-
522
- <script type="module">
523
- import AdStageSDK, { AdType } from './dist/index.standalone.js';
524
-
525
- const statusEl = document.getElementById('status');
526
- const logEl = document.getElementById('log');
527
-
528
- function addLog(message, type = 'info') {
529
- const timestamp = new Date().toLocaleTimeString();
530
- const logEntry = document.createElement('div');
531
- logEntry.className = `log-entry ${type}`;
532
- logEntry.textContent = `[${timestamp}] ${message}`;
533
- logEl.appendChild(logEntry);
534
- logEl.scrollTop = logEl.scrollHeight;
535
- }
536
-
537
- // 전역 함수들
538
- window.refreshAllNativeAds = function() {
539
- const slots = ['feed-native-1', 'feed-native-2', 'card-native-1', 'card-native-2', 'card-native-3'];
540
- slots.forEach(slotId => {
541
- addLog(`네이티브 광고 새로고침: ${slotId}`, 'info');
542
- const slot = document.getElementById(slotId);
543
- if (slot) {
544
- slot.classList.add('loading');
545
- setTimeout(() => {
546
- slot.classList.remove('loading');
547
- addLog(`네이티브 광고 로드 완료: ${slotId}`, 'info');
548
- }, Math.random() * 2000 + 500);
549
- }
550
- });
551
- };
552
-
553
- window.hideAllAds = function() {
554
- const slots = ['feed-native-1', 'feed-native-2', 'card-native-1', 'card-native-2', 'card-native-3'];
555
- slots.forEach(slotId => {
556
- const slot = document.getElementById(slotId);
557
- if (slot) {
558
- slot.style.display = 'none';
559
- addLog(`광고 숨김: ${slotId}`, 'info');
560
- }
561
- });
562
- };
563
-
564
- window.showAllAds = function() {
565
- const slots = ['feed-native-1', 'feed-native-2', 'card-native-1', 'card-native-2', 'card-native-3'];
566
- slots.forEach(slotId => {
567
- const slot = document.getElementById(slotId);
568
- if (slot) {
569
- slot.style.display = 'block';
570
- addLog(`광고 표시: ${slotId}`, 'info');
571
- }
572
- });
573
- };
574
-
575
- window.clearLog = function() {
576
- logEl.innerHTML = '<div class="log-entry info">로그가 지워졌습니다.</div>';
577
- };
578
-
579
- try {
580
- addLog('AdStage SDK 초기화 시작...', 'info');
581
-
582
- // SDK 초기화
583
- const sdk = AdStageSDK.init({
584
- apiKey: '7dfddcfda637fbb73225bac3731688b80b90675942fe9f2057a88e2379aba2a4',
585
- debug: true
586
- });
587
-
588
- window.adstageSDK = sdk;
589
-
590
- statusEl.innerHTML = '✅ SDK 초기화 완료 - 네이티브 광고 로딩 중...';
591
- statusEl.style.background = '#e2d9f3';
592
- statusEl.style.borderColor = '#6f42c1';
593
-
594
- addLog('SDK 초기화 완료', 'info');
595
-
596
- // 네이티브 광고 슬롯들 초기화
597
- document.querySelectorAll('.native-ad-slot').forEach(slot => {
598
- const slotId = slot.getAttribute('adstage');
599
-
600
- // 클릭 이벤트 추가
601
- slot.addEventListener('click', function(e) {
602
- if (e.target.classList.contains('feed-cta')) {
603
- addLog(`네이티브 광고 CTA 클릭: ${slotId}`, 'info');
604
-
605
- // 시각적 피드백
606
- e.target.style.background = '#5a2d91';
607
- setTimeout(() => {
608
- e.target.style.background = '#6f42c1';
609
- }, 200);
610
- } else {
611
- addLog(`네이티브 광고 클릭: ${slotId}`, 'info');
612
- }
613
- });
614
-
615
- // 로딩 시뮬레이션
616
- setTimeout(() => {
617
- slot.classList.remove('loading');
618
- addLog(`네이티브 광고 로드 완료: ${slotId}`, 'info');
619
- }, Math.random() * 3000 + 1000);
620
- });
621
-
622
- addLog('네이티브 광고 페이지 초기화 완료', 'info');
623
- console.log('네이티브 광고 예제 페이지 로드 완료');
624
-
625
- } catch (error) {
626
- console.error('SDK 초기화 오류:', error);
627
- addLog(`SDK 초기화 실패: ${error.message}`, 'error');
628
- statusEl.innerHTML = '❌ SDK 초기화 실패: ' + error.message;
629
- statusEl.style.background = '#f8d7da';
630
- statusEl.style.borderColor = '#dc3545';
631
- }
632
- </script>
633
- </body>
634
- </html>
@@ -1,70 +0,0 @@
1
- # AdStage SDK React 앱 예제
2
-
3
- 이 프로젝트는 Vite + React + TypeScript를 사용한 AdStage SDK 통합 예제입니다.
4
-
5
- ## 실행 방법
6
-
7
- ### 1. 의존성 설치
8
- ```bash
9
- cd /Users/gunny/Documents/workspace/adstage/sdk/examples/react-app
10
- npm install
11
- ```
12
-
13
- ### 2. SDK 빌드 (상위 디렉토리에서)
14
- ```bash
15
- cd /Users/gunny/Documents/workspace/adstage/sdk
16
- npm run build
17
- ```
18
-
19
- ### 3. 개발 서버 실행
20
- ```bash
21
- cd /Users/gunny/Documents/workspace/adstage/sdk/examples/react-app
22
- npm run dev
23
- ```
24
-
25
- 브라우저에서 `http://localhost:3000`으로 접속하여 예제를 확인할 수 있습니다.
26
-
27
- ## 주요 기능
28
-
29
- - **SDK 동적 로딩**: AdStage SDK를 동적으로 로드하고 초기화
30
- - **실시간 메트릭**: 클릭, 노출, 전환 이벤트 추적
31
- - **광고 시뮬레이션**: 배너/텍스트 광고 클릭 및 노출 시뮬레이션
32
- - **이벤트 추적**: SDK의 이벤트 추적 기능 데모
33
-
34
- ## 파일 구조
35
-
36
- ```
37
- react-app/
38
- ├── src/
39
- │ ├── App.tsx # 메인 컴포넌트
40
- │ ├── main.tsx # 엔트리 포인트
41
- │ └── index.css # 전역 스타일
42
- ├── index.html # HTML 템플릿
43
- ├── vite.config.ts # Vite 설정
44
- ├── tsconfig.json # TypeScript 설정
45
- └── package.json # 프로젝트 설정
46
- ```
47
-
48
- ## 기술 스택
49
-
50
- - **React 18**: 컴포넌트 기반 UI 라이브러리
51
- - **TypeScript**: 타입 안전성을 위한 정적 타입 언어
52
- - **Vite**: 빠른 빌드 도구 및 개발 서버
53
- - **AdStage SDK**: 광고 관리 및 이벤트 추적
54
-
55
- ## 실제 프로젝트 통합
56
-
57
- 실제 프로젝트에서는 다음과 같이 SDK를 사용할 수 있습니다:
58
-
59
- ```typescript
60
- import { AdStageSDK } from '@adstage/web-sdk';
61
-
62
- // SDK 초기화
63
- const sdk = AdStageSDK.init({
64
- apiKey: 'your-api-key',
65
- debug: process.env.NODE_ENV === 'development'
66
- });
67
-
68
- // 이벤트 추적
69
- sdk.trackEvent('CLICK', { adType: 'banner', slotId: 'banner-1' });
70
- ```