@@ -5,6 +5,7 @@ import { headers } from 'next/headers';
5
5
import { AdClassicRendering } from './AdClassicRendering' ;
6
6
import { AdCoverRendering } from './AdCoverRendering' ;
7
7
import { AdPixels } from './AdPixels' ;
8
+ import adRainbow from './assets/ad-rainbow.svg' ;
8
9
import { AdItem , AdsResponse } from './types' ;
9
10
10
11
interface FetchAdOptions {
@@ -16,6 +17,12 @@ interface FetchAdOptions {
16
17
placement : string ;
17
18
/** If true, we'll not track it as an impression */
18
19
ignore : boolean ;
20
+ /**
21
+ * Source of the ad (live: from the platform, placeholder: static placeholder)
22
+ *
23
+ * Defaults to live.
24
+ * */
25
+ source ?: 'live' | 'placeholder' ;
19
26
}
20
27
21
28
/**
@@ -24,8 +31,9 @@ interface FetchAdOptions {
24
31
* and properly access user-agent and IP.
25
32
*/
26
33
export async function renderAd ( options : FetchAdOptions ) {
27
- const { mode } = options ;
28
- const result = await fetchAd ( options ) ;
34
+ const { mode, source = 'live' } = options ;
35
+
36
+ const result = source === 'live' ? await fetchAd ( options ) : getPlaceholderAd ( ) ;
29
37
if ( ! result || ! result . ad . description || ! result . ad . statlink ) {
30
38
return null ;
31
39
}
@@ -49,15 +57,7 @@ async function fetchAd({
49
57
placement,
50
58
ignore,
51
59
} : FetchAdOptions ) : Promise < { ad : AdItem ; ip : string } | null > {
52
- const headersSet = headers ( ) ;
53
- const ip =
54
- headersSet . get ( 'x-gitbook-ipv4' ) ??
55
- headersSet . get ( 'x-gitbook-ip' ) ??
56
- headersSet . get ( 'cf-pseudo-ipv4' ) ??
57
- headersSet . get ( 'cf-connecting-ip' ) ??
58
- headersSet . get ( 'x-forwarded-for' ) ??
59
- '' ;
60
- const userAgent = headersSet . get ( 'user-agent' ) ?? '' ;
60
+ const { ip, userAgent } = getUserAgentAndIp ( ) ;
61
61
62
62
const url = new URL ( `https://srv.buysellads.com/ads/${ zoneId } .json` ) ;
63
63
url . searchParams . set ( 'segment' , `placement:${ placement } ` ) ;
@@ -78,3 +78,49 @@ async function fetchAd({
78
78
79
79
return null ;
80
80
}
81
+
82
+ function getPlaceholderAd ( ) : { ad : AdItem ; ip : string } {
83
+ const { ip } = getUserAgentAndIp ( ) ;
84
+
85
+ return {
86
+ ad : {
87
+ active : '1' ,
88
+ ad_via_link : '' ,
89
+ bannerid : '' ,
90
+ creativeid : '' ,
91
+ description :
92
+ 'Your docs could be this good.\nPublish incredible open source docs for free with GitBook' ,
93
+ evenodd : '0' ,
94
+ external_id : '' ,
95
+ height : '0' ,
96
+ i : '0' ,
97
+ identifier : '' ,
98
+ longimp : '' ,
99
+ longlink : '' ,
100
+ num_slots : '1' ,
101
+ rendering : 'carbon' ,
102
+ smallImage : adRainbow . src ,
103
+ statimp : '' ,
104
+ statlink : 'https://www.gitbook.com/solutions/open-source' ,
105
+ timestamp : Date . now ( ) . toString ( ) ,
106
+ width : '0' ,
107
+ zoneid : '' ,
108
+ zonekey : '' ,
109
+ } ,
110
+ ip,
111
+ } ;
112
+ }
113
+
114
+ function getUserAgentAndIp ( ) {
115
+ const headersSet = headers ( ) ;
116
+ const ip =
117
+ headersSet . get ( 'x-gitbook-ipv4' ) ??
118
+ headersSet . get ( 'x-gitbook-ip' ) ??
119
+ headersSet . get ( 'cf-pseudo-ipv4' ) ??
120
+ headersSet . get ( 'cf-connecting-ip' ) ??
121
+ headersSet . get ( 'x-forwarded-for' ) ??
122
+ '' ;
123
+ const userAgent = headersSet . get ( 'user-agent' ) ?? '' ;
124
+
125
+ return { ip, userAgent } ;
126
+ }
0 commit comments