Skip to content

Commit 748254f

Browse files
create sample site for deferred loading
1 parent a515bdd commit 748254f

File tree

9 files changed

+1272
-2
lines changed

9 files changed

+1272
-2
lines changed

docker-compose.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,16 @@ services:
115115
env_file:
116116
- .env
117117

118+
prebid-client-side-deferred:
119+
build:
120+
context: web-integrations/prebid-integrations
121+
dockerfile: client-side-deferred/Dockerfile
122+
ports:
123+
- "3053:3053"
124+
container_name: prebid-client-side-deferred
125+
env_file:
126+
- .env
127+
118128
# prebid + secure signals integrations
119129
prebid-secure-signals-client-side:
120130
build:

tools/reverse-proxy/default.conf.template

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ server {
1414
location / {
1515
add_header Content-Type text/html;
1616
# Use protocol-relative URLs (//) so they work with both http and https
17-
return 200 "<!DOCTYPE html><html><head><title>UID2 Sample Pages</title><style>body{font-family:Arial,sans-serif;max-width:800px;margin:50px auto;padding:20px;background:#f5f5f5}h1{color:#333}a{display:block;padding:10px;margin:5px 0;background:white;border-left:4px solid #007bff;text-decoration:none;color:#007bff;border-radius:4px}a:hover{background:#e7f3ff;border-left-color:#0056b3}.info{margin-top:30px;padding:15px;background:#fff3cd;border-left:4px solid #ffc107;border-radius:4px}</style></head><body><h1>UID2 Sample Pages</h1><p>Access services using the following subdomains:</p><a href=\"//js-client-side.${DOMAIN}\">js-client-side.${DOMAIN}</a><a href=\"//js-client-server.${DOMAIN}\">js-client-server.${DOMAIN}</a><a href=\"//js-react.${DOMAIN}\">js-react.${DOMAIN}</a><a href=\"//server-side.${DOMAIN}\">server-side.${DOMAIN}</a><a href=\"//secure-signals-client-server.${DOMAIN}\">secure-signals-client-server.${DOMAIN}</a><a href=\"//secure-signals-client-side.${DOMAIN}\">secure-signals-client-side.${DOMAIN}</a><a href=\"//secure-signals-server-side.${DOMAIN}\">secure-signals-server-side.${DOMAIN}</a><a href=\"//secure-signals-react.${DOMAIN}\">secure-signals-react.${DOMAIN}</a><a href=\"//prebid-client.${DOMAIN}\">prebid-client.${DOMAIN}</a><a href=\"//prebid-client-server.${DOMAIN}\">prebid-client-server.${DOMAIN}</a><a href=\"//prebid-secure-signals.${DOMAIN}\">prebid-secure-signals.${DOMAIN}</a><div class=\"info\"><strong>Note:</strong> For local development, add ${DOMAIN} and all subdomains to your hosts file (127.0.0.1) to use them. Example: <code>127.0.0.1 ${DOMAIN} js-client-side.${DOMAIN} ...</code></div></body></html>";
17+
return 200 "<!DOCTYPE html><html><head><title>UID2 Sample Pages</title><style>body{font-family:Arial,sans-serif;max-width:800px;margin:50px auto;padding:20px;background:#f5f5f5}h1{color:#333}a{display:block;padding:10px;margin:5px 0;background:white;border-left:4px solid #007bff;text-decoration:none;color:#007bff;border-radius:4px}a:hover{background:#e7f3ff;border-left-color:#0056b3}.info{margin-top:30px;padding:15px;background:#fff3cd;border-left:4px solid #ffc107;border-radius:4px}</style></head><body><h1>UID2 Sample Pages</h1><p>Access services using the following subdomains:</p><a href=\"//js-client-side.${DOMAIN}\">js-client-side.${DOMAIN}</a><a href=\"//js-client-server.${DOMAIN}\">js-client-server.${DOMAIN}</a><a href=\"//js-react.${DOMAIN}\">js-react.${DOMAIN}</a><a href=\"//server-side.${DOMAIN}\">server-side.${DOMAIN}</a><a href=\"//secure-signals-client-server.${DOMAIN}\">secure-signals-client-server.${DOMAIN}</a><a href=\"//secure-signals-client-side.${DOMAIN}\">secure-signals-client-side.${DOMAIN}</a><a href=\"//secure-signals-server-side.${DOMAIN}\">secure-signals-server-side.${DOMAIN}</a><a href=\"//secure-signals-react.${DOMAIN}\">secure-signals-react.${DOMAIN}</a><a href=\"//prebid-client.${DOMAIN}\">prebid-client.${DOMAIN}</a><a href=\"//prebid-client-server.${DOMAIN}\">prebid-client-server.${DOMAIN}</a><a href=\"//prebid-deferred.${DOMAIN}\">prebid-deferred.${DOMAIN} (mergeConfig example)</a><a href=\"//prebid-secure-signals.${DOMAIN}\">prebid-secure-signals.${DOMAIN}</a><div class=\"info\"><strong>Note:</strong> For local development, add ${DOMAIN} and all subdomains to your hosts file (127.0.0.1) to use them. Example: <code>127.0.0.1 ${DOMAIN} js-client-side.${DOMAIN} ...</code></div></body></html>";
1818
}
1919
}
2020

@@ -226,6 +226,24 @@ server {
226226
}
227227
}
228228

229+
# Prebid - Client Side Deferred (port 3053) - mergeConfig example
230+
server {
231+
listen 80;
232+
server_name prebid-deferred.${DOMAIN} *.prebid-deferred.${DOMAIN};
233+
234+
location / {
235+
proxy_pass http://${PREBID_CLIENT_SIDE_DEFERRED_BACKEND}:3053;
236+
proxy_redirect off;
237+
proxy_connect_timeout 5s;
238+
proxy_send_timeout 60s;
239+
proxy_read_timeout 60s;
240+
proxy_set_header Host $host;
241+
proxy_set_header X-Real-IP $remote_addr;
242+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
243+
proxy_set_header X-Forwarded-Proto $scheme;
244+
}
245+
}
246+
229247
# Prebid Secure Signals - Client Side (port 3061)
230248
server {
231249
listen 80;

tools/reverse-proxy/docker-entrypoint.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ if [ "${BACKEND_HOST+set}" = "set" ] && [ -z "$BACKEND_HOST" ]; then
2020
SECURE_SIGNALS_REACT_CLIENT_SIDE_BACKEND=${SECURE_SIGNALS_REACT_CLIENT_SIDE_BACKEND:-google-secure-signals-react-client-side}
2121
PREBID_CLIENT_BACKEND=${PREBID_CLIENT_BACKEND:-prebid-client}
2222
PREBID_CLIENT_SERVER_BACKEND=${PREBID_CLIENT_SERVER_BACKEND:-prebid-client-server}
23+
PREBID_CLIENT_SIDE_DEFERRED_BACKEND=${PREBID_CLIENT_SIDE_DEFERRED_BACKEND:-prebid-client-side-deferred}
2324
PREBID_SECURE_SIGNALS_CLIENT_SIDE_BACKEND=${PREBID_SECURE_SIGNALS_CLIENT_SIDE_BACKEND:-prebid-secure-signals-client-side}
2425
else
2526
# BACKEND_HOST is unset (defaults to localhost) or set to a value - use it for all services
@@ -34,6 +35,7 @@ else
3435
SECURE_SIGNALS_REACT_CLIENT_SIDE_BACKEND=${SECURE_SIGNALS_REACT_CLIENT_SIDE_BACKEND:-$BACKEND_HOST_VALUE}
3536
PREBID_CLIENT_BACKEND=${PREBID_CLIENT_BACKEND:-$BACKEND_HOST_VALUE}
3637
PREBID_CLIENT_SERVER_BACKEND=${PREBID_CLIENT_SERVER_BACKEND:-$BACKEND_HOST_VALUE}
38+
PREBID_CLIENT_SIDE_DEFERRED_BACKEND=${PREBID_CLIENT_SIDE_DEFERRED_BACKEND:-$BACKEND_HOST_VALUE}
3739
PREBID_SECURE_SIGNALS_CLIENT_SIDE_BACKEND=${PREBID_SECURE_SIGNALS_CLIENT_SIDE_BACKEND:-$BACKEND_HOST_VALUE}
3840
fi
3941

@@ -49,10 +51,11 @@ export SECURE_SIGNALS_SERVER_SIDE_BACKEND
4951
export SECURE_SIGNALS_REACT_CLIENT_SIDE_BACKEND
5052
export PREBID_CLIENT_BACKEND
5153
export PREBID_CLIENT_SERVER_BACKEND
54+
export PREBID_CLIENT_SIDE_DEFERRED_BACKEND
5255
export PREBID_SECURE_SIGNALS_CLIENT_SIDE_BACKEND
5356

5457
# Substitute environment variables in the template
55-
envsubst '${DOMAIN} ${JS_CLIENT_SIDE_BACKEND} ${JS_CLIENT_SERVER_BACKEND} ${JS_REACT_CLIENT_SIDE_BACKEND} ${SERVER_SIDE_BACKEND} ${SECURE_SIGNALS_CLIENT_SERVER_BACKEND} ${SECURE_SIGNALS_CLIENT_SIDE_BACKEND} ${SECURE_SIGNALS_SERVER_SIDE_BACKEND} ${SECURE_SIGNALS_REACT_CLIENT_SIDE_BACKEND} ${PREBID_CLIENT_BACKEND} ${PREBID_CLIENT_SERVER_BACKEND} ${PREBID_SECURE_SIGNALS_CLIENT_SIDE_BACKEND}' < /etc/nginx/templates/default.conf.template > /etc/nginx/conf.d/default.conf
58+
envsubst '${DOMAIN} ${JS_CLIENT_SIDE_BACKEND} ${JS_CLIENT_SERVER_BACKEND} ${JS_REACT_CLIENT_SIDE_BACKEND} ${SERVER_SIDE_BACKEND} ${SECURE_SIGNALS_CLIENT_SERVER_BACKEND} ${SECURE_SIGNALS_CLIENT_SIDE_BACKEND} ${SECURE_SIGNALS_SERVER_SIDE_BACKEND} ${SECURE_SIGNALS_REACT_CLIENT_SIDE_BACKEND} ${PREBID_CLIENT_BACKEND} ${PREBID_CLIENT_SERVER_BACKEND} ${PREBID_CLIENT_SIDE_DEFERRED_BACKEND} ${PREBID_SECURE_SIGNALS_CLIENT_SIDE_BACKEND}' < /etc/nginx/templates/default.conf.template > /etc/nginx/conf.d/default.conf
5659

5760
# Test nginx configuration
5861
nginx -t
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
FROM nginx:alpine
2+
3+
# Install gettext for envsubst
4+
RUN apk add --no-cache gettext
5+
6+
# Copy static files from client-side-deferred directory
7+
COPY client-side-deferred/app.css /usr/share/nginx/html/
8+
COPY prebid.js /usr/share/nginx/html/
9+
10+
# Copy config and HTML
11+
COPY client-side-deferred/default.conf /etc/nginx/conf.d/default.conf
12+
COPY client-side-deferred/index.html /usr/share/nginx/html/index.template.html
13+
COPY client-side-deferred/entrypoint.sh /entrypoint.sh
14+
15+
RUN chmod +x /entrypoint.sh
16+
17+
ENTRYPOINT ["/entrypoint.sh"]
18+
CMD ["nginx", "-g", "daemon off;"]
19+
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Deferred UID2/EUID Integration with Prebid.js (using mergeConfig)
2+
3+
This example demonstrates how to integrate UID2 or EUID with Prebid.js using **deferred configuration**. Unlike the standard integration where UID2/EUID is configured on page load, this pattern uses `mergeConfig()` and `refreshUserIds()` to add the identity module *after* the page has already loaded.
4+
5+
## Use Cases
6+
7+
This pattern is useful for:
8+
9+
- **Async Login**: User logs in after the page has loaded
10+
- **Delayed Consent**: Consent is given asynchronously (e.g., via a consent management platform)
11+
- **Single Page Applications (SPAs)**: Dynamic login/logout without full page reloads
12+
- **Lazy Loading**: Only load UID2/EUID when actually needed
13+
- **User State Changes**: Handle logout and re-login scenarios
14+
15+
## How It Works
16+
17+
### Standard Flow (for comparison)
18+
```javascript
19+
// Page load: UID2 configured immediately
20+
pbjs.setConfig({
21+
userSync: {
22+
userIds: [{ name: 'uid2', params: {...} }]
23+
}
24+
});
25+
```
26+
27+
### Deferred Flow (this example)
28+
```javascript
29+
// Step 1: Page load - Prebid configured WITHOUT UID2
30+
pbjs.setConfig({
31+
userSync: {
32+
syncDelay: 5000,
33+
auctionDelay: 1000,
34+
// Note: NO userIds configured here!
35+
}
36+
});
37+
38+
// Step 2: Later (after login, consent, etc.) - Add UID2 via mergeConfig
39+
pbjs.mergeConfig({
40+
userSync: {
41+
userIds: [{
42+
name: 'uid2',
43+
params: {
44+
uid2ApiBase: 'https://operator-integ.uidapi.com',
45+
46+
subscriptionId: 'your-subscription-id',
47+
serverPublicKey: 'your-server-public-key'
48+
}
49+
}]
50+
}
51+
});
52+
53+
// Step 3: Trigger user ID refresh to generate the token
54+
await pbjs.refreshUserIds();
55+
```
56+
57+
## Key Prebid.js APIs
58+
59+
| API | Purpose |
60+
|-----|---------|
61+
| `pbjs.setConfig()` | Initial configuration (without UID2) |
62+
| `pbjs.mergeConfig()` | Add/update configuration without replacing existing config |
63+
| `pbjs.refreshUserIds()` | Trigger user ID module to fetch/generate new IDs |
64+
| `pbjs.getUserIds()` | Get current user IDs (check if token was generated) |
65+
66+
## Live Examples
67+
68+
- **UID2**: [https://unifiedid.com/examples/cstg-prebid-deferred-example/](https://unifiedid.com/examples/cstg-prebid-deferred-example/)
69+
- **EUID**: [https://euid.eu/examples/cstg-prebid-deferred-example/](https://euid.eu/examples/cstg-prebid-deferred-example/)
70+
71+
## Running Locally
72+
73+
### Using Docker Compose (recommended)
74+
75+
From the repository root:
76+
77+
```bash
78+
docker compose up prebid-client-side-deferred
79+
```
80+
81+
Access at: http://localhost:3053
82+
83+
### Using the Reverse Proxy
84+
85+
```bash
86+
docker compose up
87+
```
88+
89+
Access at: http://prebid-deferred.sample-dev.com (requires hosts file configuration)
90+
91+
## Environment Variables
92+
93+
| Variable | Description | Default |
94+
|----------|-------------|---------|
95+
| `UID_CLIENT_BASE_URL` | API base URL for client-side calls | `https://operator-integ.uidapi.com` |
96+
| `UID_CSTG_SUBSCRIPTION_ID` | Your CSTG subscription ID | Test value provided |
97+
| `UID_CSTG_SERVER_PUBLIC_KEY` | Your CSTG server public key | Test value provided |
98+
| `UID_STORAGE_KEY` | localStorage key for token storage | `__uid2_advertising_token` |
99+
| `IDENTITY_NAME` | Display name (UID2 or EUID) | `UID2` |
100+
| `DOCS_BASE_URL` | Base URL for documentation links | `https://unifiedid.com/docs` |
101+
102+
## Testing Flow
103+
104+
1. **Page loads** - Observe that Prebid is loaded but UID2 shows "Not yet configured (deferred)"
105+
2. **Enter email** - Type an email address in the input field
106+
3. **Click "Configure UID2 with mergeConfig()"** - This triggers:
107+
- `pbjs.mergeConfig()` to add UID2 configuration
108+
- `pbjs.refreshUserIds()` to generate the token
109+
4. **Observe results** - Token appears in the status tables
110+
5. **Test opt-out** - Use `[email protected]` to see opt-out behavior
111+
112+
## Documentation
113+
114+
- [UID2 Client-Side Integration Guide for Prebid.js](https://unifiedid.com/docs/guides/integration-prebid-client-side)
115+
- [EUID Client-Side Integration Guide for Prebid.js](https://euid.eu/docs/guides/integration-prebid-client-side)
116+
- [Prebid.js User ID Module](https://docs.prebid.org/dev-docs/modules/userId.html)
117+
- [Prebid.js setConfig/mergeConfig](https://docs.prebid.org/dev-docs/publisher-api-reference/setConfig.html)
118+
119+
## Related Examples
120+
121+
- [client-side](../client-side/) - Standard Prebid + UID2 (configured on page load)
122+
- [client-server](../client-server/) - Server-side token generation with Prebid
123+

0 commit comments

Comments
 (0)