From 1d46302031790bbfb7ea0c7f95c8880297587cfb Mon Sep 17 00:00:00 2001 From: Eiman Eltigani Date: Fri, 21 Nov 2025 11:43:26 -0500 Subject: [PATCH 01/11] update design for js sdk client side --- .../client-side/html/index.html | 164 +++++-- .../client-side/html/stylesheets/app.css | 435 ++++++++++++++---- 2 files changed, 484 insertions(+), 115 deletions(-) diff --git a/web-integrations/javascript-sdk/client-side/html/index.html b/web-integrations/javascript-sdk/client-side/html/index.html index 8ad76e0..154ede4 100644 --- a/web-integrations/javascript-sdk/client-side/html/index.html +++ b/web-integrations/javascript-sdk/client-side/html/index.html @@ -13,8 +13,6 @@ serverPublicKey: '${SERVER_PUBLIC_KEY}', }; - let callbackCounter = 0; - // __uid2 for UID2 SDK, __euid for EUID SDK. const sdkName = '${UID_JS_SDK_NAME}'; @@ -30,7 +28,6 @@ sdk.isLoginRequired() || sdk.isLoginRequired() === undefined ? 'yes' : 'no' ); $(`#has_opted_out`).text(sdk.hasOptedOut() ? 'yes' : 'no'); - $('#update_counter').text(callbackCounter); $('#identity_state').text(String(JSON.stringify(state, null, 2))); updateSharedGuiElements(); @@ -47,12 +44,6 @@ } function onIdentityUpdated(eventType, payload) { - if ( - payload?.identity && - (eventType === 'InitCompleted' || eventType === 'IdentityUpdated') - ) { - ++callbackCounter; - } updateGuiElements(payload); } @@ -89,40 +80,90 @@ -

Client-Side ${IDENTITY_NAME} Integration Example using JavaScript SDK

-

- This example demonstrates how a content publisher can follow the - Client-Side Integration Guide for JavaScript - - to implement ${IDENTITY_NAME} integration and generate ${IDENTITY_NAME} tokens. - Note: This is a test-only integration environment—not for production - use. It does not perform real user authentication or generate production-level tokens. Do not - use real user data on this page. -

- +
+ +
+

Client-Side ${IDENTITY_NAME} Integration Example using JavaScript SDK

+

+ This example demonstrates how a content publisher can follow the + Client-Side Integration Guide for JavaScript + + to implement ${IDENTITY_NAME} integration and generate ${IDENTITY_NAME} tokens. + Note: This is a test-only integration environment—not for production + use. It does not perform real user authentication or generate production-level tokens. Do not + use real user data on this page. +

+

${IDENTITY_NAME} Integration Status

+
- + - + - + - + - - - - - +
Ready for Targeted Advertising: +
+ Ready for Targeted Advertising: +
+ ? +
+ Indicates whether a valid advertising token is available for use in targeted advertising. Returns "yes" when the SDK has successfully generated or refreshed a token. +
+
+
+
Advertising Token: +
+ Advertising Token: +
+ ? +
+ The ${IDENTITY_NAME} token used for targeted advertising. This token is passed to advertising partners and automatically refreshed by the SDK in the background. +
+
+
+
Is Login Required? +
+ Is Login Required? +
+ ? +
+ Indicates whether the user needs to generate a new ${IDENTITY_NAME} token. Returns "yes" when no valid identity exists or the current identity has expired. +
+
+
+
Has opted out? +
+ Has opted out? +
+ ? +
+ Indicates whether the user has opted out of ${IDENTITY_NAME}. When "yes", no advertising token will be generated and targeted advertising should not be enabled. +
+
+
+
Identity Updated Counter:
Identity Callback State: +
+ Identity Callback State: +
+ ? +
+ The complete identity object returned by the SDK. Contains the full ${IDENTITY_NAME} identity data including refresh tokens and metadata. Used for debugging and verification. +
+
+
+
@@ -133,15 +174,68 @@

Client-Side ${IDENTITY_NAME} Integration Example using JavaScript SDK

id="email" name="email" placeholder="Enter an email address" - style="border-style: none" /> + -
>
+ + + + diff --git a/web-integrations/javascript-sdk/client-side/html/stylesheets/app.css b/web-integrations/javascript-sdk/client-side/html/stylesheets/app.css index f013f06..23803e7 100644 --- a/web-integrations/javascript-sdk/client-side/html/stylesheets/app.css +++ b/web-integrations/javascript-sdk/client-side/html/stylesheets/app.css @@ -1,114 +1,389 @@ +/* Two-Column Layout with Sidebar - Modern Design */ +:root { + --primary-orange: #FF6B35; + --primary-dark: #2D3748; + --accent-teal: #0D9488; + --accent-yellow: #FBBF24; + --text-dark: #1A202C; + --text-gray: #718096; + --border-color: #E2E8F0; + --bg-light: #F7FAFC; + --bg-white: #FFFFFF; + --sidebar-bg: #FFF7ED; + --shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); + --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1); +} + +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + body { - padding: 50px; - font: 14px 'Lucida Grande', Helvetica, Arial, sans-serif; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', sans-serif; + background: var(--bg-light); + color: var(--text-dark); + line-height: 1.6; + padding: 2rem; +} + +/* Two Column Layout */ +.page-wrapper { + display: flex; + gap: 2rem; + max-width: 1400px; + margin: 0 auto; +} + +/* Main Content Area (75%) */ +.main-content { + flex: 3; + background: var(--bg-white); + border-radius: 12px; + padding: 2.5rem; + box-shadow: var(--shadow-md); +} + +/* Sidebar (25%) */ +.sidebar { + flex: 1; + background: var(--sidebar-bg); + border-radius: 12px; + padding: 2rem; + box-shadow: var(--shadow); + border-left: 4px solid var(--primary-orange); + position: sticky; + top: 2rem; + height: fit-content; + max-height: calc(100vh - 4rem); + overflow-y: auto; +} + +.sidebar h3 { + color: var(--primary-dark); + font-size: 1.1rem; + margin-bottom: 1rem; + padding-bottom: 0.5rem; + border-bottom: 2px solid var(--primary-orange); +} + +.sidebar .section { + margin-bottom: 1.5rem; +} + +.sidebar .section h4 { + color: var(--accent-teal); + font-size: 0.9rem; + font-weight: 600; + margin-bottom: 0.5rem; +} + +.sidebar ul { + margin-left: 1.25rem; + font-size: 0.875rem; + color: var(--text-gray); +} + +.sidebar li { + margin-bottom: 0.5rem; + line-height: 1.6; +} + +.sidebar .note { + background: rgba(255, 107, 53, 0.1); + padding: 0.75rem; + border-radius: 6px; + font-size: 0.85rem; + color: var(--text-dark); + margin-top: 1rem; +} + +.sidebar .note strong { + color: var(--primary-orange); +} + +/* Header */ +h1 { + font-size: 2rem; + font-weight: 800; + color: var(--primary-dark); + margin-bottom: 0.75rem; + line-height: 1.3; +} + +h2 { + font-size: 1.5rem; + font-weight: 700; + color: var(--primary-dark); + margin: 2rem 0 1rem 0; + padding-bottom: 0.5rem; + border-bottom: 3px solid var(--primary-orange); +} + +p { + font-size: 0.95rem; + color: var(--text-gray); + margin-bottom: 2rem; + line-height: 1.8; } a { - color: #00b7ff; + color: #0459fd; /* Self-serve portal link color */ + text-decoration: none; + font-weight: 600; + border-bottom: 2px solid transparent; + transition: border-color 0.2s ease; +} + +a:hover { + border-bottom-color: #0459fd; +} + +/* State Table */ +#uid2_state { + width: 100%; + border-collapse: collapse; + margin: 2rem 0; + font-size: 0.875rem; + border: 1px solid var(--border-color); + border-radius: 8px; + overflow: hidden; +} + +#uid2_state tr { + border-bottom: 1px solid var(--border-color); +} + +#uid2_state tr:nth-child(even) { + background-color: var(--bg-light); +} + +#uid2_state tr:last-child { + border-bottom: none; +} + +#uid2_state td { + padding: 1rem; + vertical-align: top; +} + +.label { + font-weight: 600; + color: var(--text-dark); + white-space: nowrap; + padding-right: 2rem; + width: 15em; +} + +.value { + color: var(--text-gray); + font-family: 'SF Mono', 'Monaco', 'Consolas', monospace; +} + +.value pre { + white-space: pre-wrap; + word-break: break-all; + margin: 0; +} + +/* Forms */ +.form { + margin-top: 2rem; +} + +.email_prompt { + display: flex; + gap: 0; + max-width: 600px; + box-shadow: var(--shadow); + border-radius: 8px; + overflow: hidden; +} + +#email { + flex: 1; + padding: 0.875rem 1.25rem; + border: 2px solid var(--border-color); + border-right: none; + font-size: 0.95rem; + color: var(--text-dark); + outline: none; + transition: border-color 0.2s ease; +} + +#email:focus { + border-color: var(--primary-orange); +} + +#email::placeholder { + color: var(--text-gray); } +/* Buttons */ .button { - border-style: none; - cursor: pointer; - align-items: center; - height: 40px; - width: 401px; - text-align: center; - position: absolute; - letter-spacing: 0.28px; - box-sizing: border-box; + padding: 0.875rem 2rem; + background: linear-gradient(135deg, var(--primary-orange) 0%, #FF8566 100%); color: white; - font-family: 'Raleway', Helvetica, Arial, serif; - font-size: 14px; - font-style: normal; + border: none; + font-size: 0.95rem; font-weight: 700; - text-transform: none; - text-indent: 0; - text-shadow: none; - margin: 0; - padding: 1px 6px; - background-color: rgba(2, 10, 64); - border-image: initial; + cursor: pointer; + transition: all 0.2s ease; + white-space: nowrap; + box-shadow: var(--shadow); } -.form { - margin-top: 40px; +.button:hover { + transform: translateY(-2px); + box-shadow: 0 6px 12px rgba(255, 107, 53, 0.3); +} + +.button:active { + transform: translateY(0); +} + +/* Full width button for logout */ +#logout_form .button { + width: 100%; + max-width: 600px; + border-radius: 8px; +} + +/* Success Message */ +.message { + background: linear-gradient(135deg, rgba(34, 197, 94, 0.1) 0%, rgba(34, 197, 94, 0.05) 100%); + border-left: 4px solid #22C55E; + color: #15803D; + padding: 1.25rem; + margin: 1.5rem 0; + font-size: 0.95rem; + font-weight: 600; + border-radius: 6px; } .product-tables { display: flex; flex-direction: row; + gap: 2rem; + margin-top: 2rem; } -.email_prompt { - align-items: center; - align-self: center; - background-color: white; - border: 1px solid rgba(2, 10, 64); - border-radius: 2px; - box-sizing: border-box; +/* Tooltip Styles - Matching Self-Serve Portal */ +.tooltip-wrapper { display: inline-flex; - flex-direction: row; - flex-shrink: 0; - height: 40px; - justify-content: flex-start; - margin-right: 1px; - margin-bottom: 20px; - min-width: 399px; - padding: 0 16px; - position: relative; - width: auto; + align-items: center; + gap: 0.5rem; } -table { - border: 1px solid; - width: 100%; +.tooltip { + position: relative; + display: inline-flex; + align-items: center; + cursor: help; } -#email { - background-color: white; +.tooltip-trigger { + width: 16px; + height: 16px; + border-radius: 50%; + background-color: #3B82F6; /* Info blue color matching portal */ + color: white; + border: none; + font-size: 0.7rem; + font-weight: 700; + display: flex; + align-items: center; + justify-content: center; + cursor: help; + transition: all 0.2s ease; flex-shrink: 0; - height: auto; - letter-spacing: 0.12px; - line-height: 16px; - min-height: 16px; - position: relative; - text-align: left; - white-space: nowrap; - width: 351px; - color: rgba(2, 10, 64, 1); - font-family: 'Raleway', Helvetica, Arial, serif; - font-size: 12px; - font-style: normal; - font-weight: 500; - padding: 1px 2px; - outline: none; } -h1 { - padding-bottom: 20px; +.tooltip-trigger:hover { + background-color: #2563EB; + transform: scale(1.05); } -.label { - white-space: nowrap; - padding-right: 20px; - width: 20em; +.tooltip-content { + visibility: hidden; + opacity: 0; + position: absolute; + bottom: calc(100% + 8px); /* Position above with gap */ + left: 50%; + transform: translateX(-50%); + background-color: #1F2937; /* Dark sidepanel color matching portal */ + color: white; + padding: 10px; + border-radius: 4px; + font-size: 0.75rem; + line-height: 1.125; /* Exact line-height from portal */ + min-width: 300px; /* Minimum width to ensure wider tooltips */ + max-width: 570px; /* 3x wider for better text flow */ + white-space: normal; + z-index: 10000; /* High z-index to prevent cutoff */ + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + transition: opacity 0.2s ease, visibility 0.2s ease; + font-weight: 400; + pointer-events: none; } -tr { - margin-top: 10px; + +.tooltip-content::after { + content: ''; + position: absolute; + top: 100%; + left: 50%; + transform: translateX(-50%); + border-width: 6px; + border-style: solid; + border-color: #1F2937 transparent transparent transparent; } -pre { - white-space: pre-wrap; - word-break: break-all; +.tooltip:hover .tooltip-content { + visibility: visible; + opacity: 1; } -.message { - color: green; - padding: 20px; - margin-left: -22px; - font-size: 16px; - font-weight: 500; - border: 2px solid green; - border-radius: 5px; +/* Ensure table doesn't clip tooltips */ +#uid2_state { + position: relative; + overflow: visible; +} + +/* Responsive Design */ +@media (max-width: 1024px) { + .page-wrapper { + flex-direction: column; + } + + .sidebar { + position: static; + max-height: none; + order: -1; /* Put sidebar on top on mobile */ + } + + body { + padding: 1rem; + } + + .main-content { + padding: 1.5rem; + } + + h1 { + font-size: 1.5rem; + } + + .email_prompt { + flex-direction: column; + } + + #email { + border-right: 2px solid var(--border-color); + border-bottom: none; + } + + .button { + width: 100%; + } } From 944198ac2ede24bff134d97762da8de965d5a146 Mon Sep 17 00:00:00 2001 From: Eiman Eltigani Date: Fri, 21 Nov 2025 11:57:48 -0500 Subject: [PATCH 02/11] clean up stylesheet comments --- .../client-side/html/stylesheets/app.css | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/web-integrations/javascript-sdk/client-side/html/stylesheets/app.css b/web-integrations/javascript-sdk/client-side/html/stylesheets/app.css index 23803e7..c85d9a7 100644 --- a/web-integrations/javascript-sdk/client-side/html/stylesheets/app.css +++ b/web-integrations/javascript-sdk/client-side/html/stylesheets/app.css @@ -287,7 +287,7 @@ a:hover { width: 16px; height: 16px; border-radius: 50%; - background-color: #3B82F6; /* Info blue color matching portal */ + background-color: #3B82F6; color: white; border: none; font-size: 0.7rem; @@ -312,16 +312,16 @@ a:hover { bottom: calc(100% + 8px); /* Position above with gap */ left: 50%; transform: translateX(-50%); - background-color: #1F2937; /* Dark sidepanel color matching portal */ + background-color: #1F2937; color: white; padding: 10px; border-radius: 4px; font-size: 0.75rem; - line-height: 1.125; /* Exact line-height from portal */ - min-width: 300px; /* Minimum width to ensure wider tooltips */ - max-width: 570px; /* 3x wider for better text flow */ + line-height: 1.125; + min-width: 300px; + max-width: 570px; white-space: normal; - z-index: 10000; /* High z-index to prevent cutoff */ + z-index: 10000; box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); transition: opacity 0.2s ease, visibility 0.2s ease; font-weight: 400; @@ -350,7 +350,6 @@ a:hover { overflow: visible; } -/* Responsive Design */ @media (max-width: 1024px) { .page-wrapper { flex-direction: column; @@ -359,7 +358,6 @@ a:hover { .sidebar { position: static; max-height: none; - order: -1; /* Put sidebar on top on mobile */ } body { @@ -370,10 +368,6 @@ a:hover { padding: 1.5rem; } - h1 { - font-size: 1.5rem; - } - .email_prompt { flex-direction: column; } From f724d53e901222fe0b29e10043e1968c5c0515de Mon Sep 17 00:00:00 2001 From: Eiman Eltigani Date: Mon, 24 Nov 2025 11:50:40 -0500 Subject: [PATCH 03/11] update button color and extract colors to global theme --- .../client-side/html/index.html | 6 +-- .../client-side/html/stylesheets/app.css | 28 ++++++++--- web-integrations/styles/colors.scss | 31 +++++++++++++ web-integrations/styles/themes.css | 46 +++++++++++++++++++ web-integrations/styles/themes.scss | 39 ++++++++++++++++ 5 files changed, 140 insertions(+), 10 deletions(-) create mode 100644 web-integrations/styles/colors.scss create mode 100644 web-integrations/styles/themes.css create mode 100644 web-integrations/styles/themes.scss diff --git a/web-integrations/javascript-sdk/client-side/html/index.html b/web-integrations/javascript-sdk/client-side/html/index.html index 154ede4..8802c45 100644 --- a/web-integrations/javascript-sdk/client-side/html/index.html +++ b/web-integrations/javascript-sdk/client-side/html/index.html @@ -117,7 +117,7 @@

${IDENTITY_NAME} Integration Status

?
- The ${IDENTITY_NAME} token used for targeted advertising. This token is passed to advertising partners and automatically refreshed by the SDK in the background. + This token is passed to the bidstream and used for targeted advertising. It is automatically refreshed by the SDK in the background when expired.
@@ -131,7 +131,7 @@

${IDENTITY_NAME} Integration Status

?
- Indicates whether the user needs to generate a new ${IDENTITY_NAME} token. Returns "yes" when no valid identity exists or the current identity has expired. + Indicates whether a new ${IDENTITY_NAME} token needs to be generated. Returns "yes" when no valid identity exists or the current identity has expired.
@@ -228,7 +228,7 @@

What's Happening?

  • Client-Side Token Generation: The SDK generates tokens directly in the browser using your public credentials
  • Auto-Refresh: Tokens are automatically refreshed in the background to maintain up-to-date identity
  • -
  • Local Storage: Identity is stored in browser storage for persistence across page loads
  • +
  • Local Storage: Identity is stored in localStorage (__uid2_advertising_token or __euid_advertising_token) for persistence across page loads
diff --git a/web-integrations/javascript-sdk/client-side/html/stylesheets/app.css b/web-integrations/javascript-sdk/client-side/html/stylesheets/app.css index c85d9a7..d09aa23 100644 --- a/web-integrations/javascript-sdk/client-side/html/stylesheets/app.css +++ b/web-integrations/javascript-sdk/client-side/html/stylesheets/app.css @@ -12,6 +12,19 @@ --sidebar-bg: #FFF7ED; --shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1); + + /* Button Colors */ + --button-navy: rgba(2, 10, 64, 1); + --button-navy-hover: rgba(2, 10, 64, 0.9); + + /* Link Colors */ + --link-color: #0459fd; + --link-hover: #0347cc; + + /* Tooltip Colors */ + --tooltip-bg: #1F2937; + --tooltip-trigger: #3B82F6; + --tooltip-trigger-hover: #2563EB; } * { @@ -129,7 +142,7 @@ p { } a { - color: #0459fd; /* Self-serve portal link color */ + color: var(--link-color); text-decoration: none; font-weight: 600; border-bottom: 2px solid transparent; @@ -137,7 +150,7 @@ a { } a:hover { - border-bottom-color: #0459fd; + border-bottom-color: var(--link-color); } /* State Table */ @@ -223,7 +236,7 @@ a:hover { /* Buttons */ .button { padding: 0.875rem 2rem; - background: linear-gradient(135deg, var(--primary-orange) 0%, #FF8566 100%); + background: var(--button-navy); color: white; border: none; font-size: 0.95rem; @@ -235,8 +248,9 @@ a:hover { } .button:hover { + background: var(--button-navy-hover); transform: translateY(-2px); - box-shadow: 0 6px 12px rgba(255, 107, 53, 0.3); + box-shadow: 0 6px 12px rgba(2, 10, 64, 0.3); } .button:active { @@ -287,7 +301,7 @@ a:hover { width: 16px; height: 16px; border-radius: 50%; - background-color: #3B82F6; + background-color: var(--tooltip-trigger); color: white; border: none; font-size: 0.7rem; @@ -301,7 +315,7 @@ a:hover { } .tooltip-trigger:hover { - background-color: #2563EB; + background-color: var(--tooltip-trigger-hover); transform: scale(1.05); } @@ -312,7 +326,7 @@ a:hover { bottom: calc(100% + 8px); /* Position above with gap */ left: 50%; transform: translateX(-50%); - background-color: #1F2937; + background-color: var(--tooltip-bg); color: white; padding: 10px; border-radius: 4px; diff --git a/web-integrations/styles/colors.scss b/web-integrations/styles/colors.scss new file mode 100644 index 0000000..a841c4a --- /dev/null +++ b/web-integrations/styles/colors.scss @@ -0,0 +1,31 @@ +// Brand Colors +$color-primary-orange: #FF6B35; +$color-primary-dark: #2D3748; +$color-accent-teal: #0D9488; +$color-accent-yellow: #FBBF24; + +// Text Colors +$color-text-dark: #1A202C; +$color-text-gray: #718096; + +// Background Colors +$color-bg-white: #FFFFFF; +$color-bg-light: #F7FAFC; +$color-sidebar-bg: #FFF7ED; + +// Border & Shadow Colors +$color-border: #E2E8F0; + +// Button Colors +$color-button-navy: rgba(2, 10, 64, 1); +$color-button-navy-hover: rgba(2, 10, 64, 0.9); + +// Link Colors +$color-link: #0459fd; +$color-link-hover: #0347cc; + +// Tooltip Colors +$color-tooltip-bg: #1F2937; +$color-tooltip-trigger: #3B82F6; +$color-tooltip-trigger-hover: #2563EB; + diff --git a/web-integrations/styles/themes.css b/web-integrations/styles/themes.css new file mode 100644 index 0000000..ce97fa2 --- /dev/null +++ b/web-integrations/styles/themes.css @@ -0,0 +1,46 @@ +/* + * Centralized UID2 Examples Theme Variables + * + * This file defines the color palette and design tokens used across all UID2 example sites. + * To use in your site, either: + * 1. Link this file in your HTML: + * 2. Copy these :root variables into your site's CSS file + */ + +:root { + /* Brand Colors */ + --primary-orange: #FF6B35; + --primary-dark: #2D3748; + --accent-teal: #0D9488; + --accent-yellow: #FBBF24; + + /* Text Colors */ + --text-dark: #1A202C; + --text-gray: #718096; + + /* Background Colors */ + --bg-white: #FFFFFF; + --bg-light: #F7FAFC; + --sidebar-bg: #FFF7ED; + + /* Border Colors */ + --border-color: #E2E8F0; + + /* Button Colors */ + --button-navy: rgba(2, 10, 64, 1); + --button-navy-hover: rgba(2, 10, 64, 0.9); + + /* Link Colors */ + --link-color: #0459fd; + --link-hover: #0347cc; + + /* Tooltip Colors */ + --tooltip-bg: #1F2937; + --tooltip-trigger: #3B82F6; + --tooltip-trigger-hover: #2563EB; + + /* Shadows */ + --shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); + --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1); +} + diff --git a/web-integrations/styles/themes.scss b/web-integrations/styles/themes.scss new file mode 100644 index 0000000..96de43a --- /dev/null +++ b/web-integrations/styles/themes.scss @@ -0,0 +1,39 @@ +@use "colors" as *; + +:root { + /* Brand Colors */ + --primary-orange: #{$color-primary-orange}; + --primary-dark: #{$color-primary-dark}; + --accent-teal: #{$color-accent-teal}; + --accent-yellow: #{$color-accent-yellow}; + + /* Text Colors */ + --text-dark: #{$color-text-dark}; + --text-gray: #{$color-text-gray}; + + /* Background Colors */ + --bg-white: #{$color-bg-white}; + --bg-light: #{$color-bg-light}; + --sidebar-bg: #{$color-sidebar-bg}; + + /* Border Colors */ + --border-color: #{$color-border}; + + /* Button Colors */ + --button-navy: #{$color-button-navy}; + --button-navy-hover: #{$color-button-navy-hover}; + + /* Link Colors */ + --link-color: #{$color-link}; + --link-hover: #{$color-link-hover}; + + /* Tooltip Colors */ + --tooltip-bg: #{$color-tooltip-bg}; + --tooltip-trigger: #{$color-tooltip-trigger}; + --tooltip-trigger-hover: #{$color-tooltip-trigger-hover}; + + /* Shadows */ + --shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); + --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1); +} + From 2e9eaed69f5f016c38cb434c4901b23b2e8fdb0f Mon Sep 17 00:00:00 2001 From: Eiman Eltigani Date: Mon, 24 Nov 2025 18:24:31 -0500 Subject: [PATCH 04/11] apply styling to prebid-secure-signals --- .../javascript-sdk/client-side/Dockerfile | 3 + .../client-side/html/index.html | 3 - .../client-side/html/stylesheets/app.css | 39 +- .../client-side/Dockerfile | 3 + .../prebid-secure-signals/client-side/ads.css | 3 +- .../prebid-secure-signals/client-side/app.css | 446 +++++++++++++----- .../client-side/index.html | 132 +++++- .../styles/{themes.css => colors.css} | 12 +- web-integrations/styles/colors.scss | 31 -- web-integrations/styles/themes.scss | 39 -- 10 files changed, 456 insertions(+), 255 deletions(-) rename web-integrations/styles/{themes.css => colors.css} (66%) delete mode 100644 web-integrations/styles/colors.scss delete mode 100644 web-integrations/styles/themes.scss diff --git a/web-integrations/javascript-sdk/client-side/Dockerfile b/web-integrations/javascript-sdk/client-side/Dockerfile index 2084afd..2d58e52 100644 --- a/web-integrations/javascript-sdk/client-side/Dockerfile +++ b/web-integrations/javascript-sdk/client-side/Dockerfile @@ -6,6 +6,9 @@ RUN apk add --no-cache gettext # Copy static files from client-side directory COPY web-integrations/javascript-sdk/client-side/html /usr/share/nginx/html/ +# Copy shared styles folder +COPY web-integrations/styles /usr/share/nginx/html/styles/ + # Copy config and entrypoint COPY web-integrations/javascript-sdk/client-side/default.conf /etc/nginx/conf.d/default.conf COPY web-integrations/javascript-sdk/client-side/entrypoint.sh /entrypoint.sh diff --git a/web-integrations/javascript-sdk/client-side/html/index.html b/web-integrations/javascript-sdk/client-side/html/index.html index 8802c45..deffea9 100644 --- a/web-integrations/javascript-sdk/client-side/html/index.html +++ b/web-integrations/javascript-sdk/client-side/html/index.html @@ -90,9 +90,6 @@

Client-Side ${IDENTITY_NAME} Integration Example using JavaScript SDK

>Client-Side Integration Guide for JavaScript to implement ${IDENTITY_NAME} integration and generate ${IDENTITY_NAME} tokens. - Note: This is a test-only integration environment—not for production - use. It does not perform real user authentication or generate production-level tokens. Do not - use real user data on this page.

${IDENTITY_NAME} Integration Status

diff --git a/web-integrations/javascript-sdk/client-side/html/stylesheets/app.css b/web-integrations/javascript-sdk/client-side/html/stylesheets/app.css index d09aa23..5d5b2ac 100644 --- a/web-integrations/javascript-sdk/client-side/html/stylesheets/app.css +++ b/web-integrations/javascript-sdk/client-side/html/stylesheets/app.css @@ -1,31 +1,5 @@ -/* Two-Column Layout with Sidebar - Modern Design */ -:root { - --primary-orange: #FF6B35; - --primary-dark: #2D3748; - --accent-teal: #0D9488; - --accent-yellow: #FBBF24; - --text-dark: #1A202C; - --text-gray: #718096; - --border-color: #E2E8F0; - --bg-light: #F7FAFC; - --bg-white: #FFFFFF; - --sidebar-bg: #FFF7ED; - --shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); - --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1); - - /* Button Colors */ - --button-navy: rgba(2, 10, 64, 1); - --button-navy-hover: rgba(2, 10, 64, 0.9); - - /* Link Colors */ - --link-color: #0459fd; - --link-hover: #0347cc; - - /* Tooltip Colors */ - --tooltip-bg: #1F2937; - --tooltip-trigger: #3B82F6; - --tooltip-trigger-hover: #2563EB; -} +/* Import centralized color variables */ +@import url('../styles/colors.css'); * { box-sizing: border-box; @@ -143,14 +117,13 @@ p { a { color: var(--link-color); - text-decoration: none; - font-weight: 600; - border-bottom: 2px solid transparent; - transition: border-color 0.2s ease; + text-decoration: underline; + font-weight: 500; + transition: opacity 0.2s ease; } a:hover { - border-bottom-color: var(--link-color); + opacity: 0.8; } /* State Table */ diff --git a/web-integrations/prebid-secure-signals/client-side/Dockerfile b/web-integrations/prebid-secure-signals/client-side/Dockerfile index 49fd84c..3715fbf 100644 --- a/web-integrations/prebid-secure-signals/client-side/Dockerfile +++ b/web-integrations/prebid-secure-signals/client-side/Dockerfile @@ -9,6 +9,9 @@ COPY web-integrations/prebid-secure-signals/client-side/ads.css /usr/share/nginx COPY web-integrations/prebid-secure-signals/client-side/ads.js /usr/share/nginx/html/ COPY web-integrations/prebid-secure-signals/prebid.js /usr/share/nginx/html/ +# Copy shared styles folder +COPY web-integrations/styles /usr/share/nginx/html/styles/ + # Copy config and HTML template COPY web-integrations/prebid-secure-signals/client-side/default.conf /etc/nginx/conf.d/default.conf COPY web-integrations/prebid-secure-signals/client-side/index.html /usr/share/nginx/html/index.template.html diff --git a/web-integrations/prebid-secure-signals/client-side/ads.css b/web-integrations/prebid-secure-signals/client-side/ads.css index 7478c85..991bf6f 100644 --- a/web-integrations/prebid-secure-signals/client-side/ads.css +++ b/web-integrations/prebid-secure-signals/client-side/ads.css @@ -3,7 +3,7 @@ /* this element's width controls the effective height */ /* of the video container's padding-bottom */ max-width: 640px; - margin: 10px 0; + margin: 2rem 0; } #video-container { @@ -11,6 +11,7 @@ /* forces the container to match a 16x9 aspect ratio */ /* replace with 75% for a 4:3 aspect ratio, if needed */ padding-bottom: 56.25%; + background: #000; } #video-element { diff --git a/web-integrations/prebid-secure-signals/client-side/app.css b/web-integrations/prebid-secure-signals/client-side/app.css index 2ced165..9611f3d 100644 --- a/web-integrations/prebid-secure-signals/client-side/app.css +++ b/web-integrations/prebid-secure-signals/client-side/app.css @@ -1,175 +1,383 @@ +/* Two-Column Layout with Sidebar - Modern Design */ +/* Import centralized color variables */ +@import url('../styles/colors.css'); + +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + body { - padding: 50px; - font: - 14px 'Lucida Grande', - Helvetica, - Arial, - sans-serif; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', sans-serif; + background: var(--bg-light); + color: var(--text-dark); + line-height: 1.6; + padding: 2rem; } -a { - color: #00b7ff; +/* Two Column Layout */ +.page-wrapper { + display: flex; + gap: 2rem; + max-width: 1400px; + margin: 0 auto; } -.button { - border-style: none; - cursor: pointer; - align-items: center; - height: 40px; - width: 401px; - text-align: center; - position: absolute; - letter-spacing: 0.28px; - box-sizing: border-box; - color: white; - font-family: 'Raleway', Helvetica, Arial, serif; - font-size: 14px; - font-style: normal; - font-weight: 700; - text-transform: none; - text-indent: 0; - text-shadow: none; - margin: 0; - padding: 1px 6px; - background-color: rgba(2, 10, 64); - border-image: initial; +/* Main Content Area (75%) */ +.main-content { + flex: 3; + background: var(--bg-white); + border-radius: 12px; + padding: 2.5rem; + box-shadow: var(--shadow-md); } -.form { - margin-top: 40px; +/* Sidebar (25%) */ +.sidebar { + flex: 1; + background: var(--sidebar-bg); + border-radius: 12px; + padding: 2rem; + box-shadow: var(--shadow); + border-left: 4px solid var(--primary-orange); + position: sticky; + top: 2rem; + height: fit-content; + max-height: calc(100vh - 4rem); + overflow-y: auto; } -.email_prompt { - align-items: center; - align-self: center; - background-color: white; - border: 1px solid rgba(2, 10, 64); - border-radius: 2px; - box-sizing: border-box; - display: inline-flex; - flex-direction: row; - flex-shrink: 0; - height: 40px; - justify-content: flex-start; - margin-right: 1px; - margin-bottom: 20px; - min-width: 399px; - padding: 0 16px; - position: relative; - width: auto; +.sidebar h3 { + color: var(--primary-dark); + font-size: 1.1rem; + margin-bottom: 1rem; + padding-bottom: 0.5rem; + border-bottom: 2px solid var(--primary-orange); } -#email { - background-color: white; - flex-shrink: 0; - height: auto; - letter-spacing: 0.12px; - line-height: 16px; - min-height: 16px; - position: relative; - text-align: left; - white-space: nowrap; - width: 351px; - color: rgba(2, 10, 64, 1); - font-family: 'Raleway', Helvetica, Arial, serif; - font-size: 12px; - font-style: normal; - font-weight: 500; - padding: 1px 2px; - outline: none; +.sidebar .section { + margin-bottom: 1.5rem; +} + +.sidebar .section h4 { + color: var(--accent-teal); + font-size: 0.9rem; + font-weight: 600; + margin-bottom: 0.5rem; +} + +.sidebar ul { + margin-left: 1.25rem; + font-size: 0.875rem; + color: var(--text-gray); +} + +.sidebar li { + margin-bottom: 0.5rem; + line-height: 1.6; +} + +.sidebar .note { + background: rgba(255, 107, 53, 0.1); + padding: 0.75rem; + border-radius: 6px; + font-size: 0.85rem; + color: var(--text-dark); + margin-top: 1rem; } +.sidebar .note strong { + color: var(--primary-orange); +} + +/* Header */ h1 { - padding-bottom: 20px; + font-size: 2rem; + font-weight: 800; + color: var(--primary-dark); + margin-bottom: 0.75rem; + line-height: 1.3; } h2 { - margin-top: 40px; - margin-bottom: 10px; - color: rgba(2, 10, 64); + font-size: 1.5rem; + font-weight: 700; + color: var(--primary-dark); + margin: 2rem 0 1rem 0; + padding-bottom: 0.5rem; + border-bottom: 3px solid var(--primary-orange); } .intro { - line-height: 1.6; - margin-bottom: 20px; + font-size: 0.95rem; + color: var(--text-gray); + margin-bottom: 2rem; + line-height: 1.8; } -.intro ul { - margin-top: 10px; +a { + color: var(--link-color); + text-decoration: underline; + font-weight: 500; + transition: opacity 0.2s ease; +} + +a:hover { + opacity: 0.8; } -table { +/* Video Container - Styles are in ads.css */ + +/* Integration State Table */ +#integration_state { width: 100%; + border-collapse: separate; + border-spacing: 0; + margin: 2rem 0; + border: 2px solid var(--border-color); + border-radius: 8px; + overflow: hidden; + font-size: 0.875rem; +} + +#integration_state tr { + border-bottom: 1px solid var(--border-color); +} + +#integration_state tr:last-child { + border-bottom: none; +} + +#integration_state tr:nth-child(even) { + background-color: var(--bg-light); +} + +#integration_state td { + padding: 1rem; + vertical-align: top; } .label { + font-weight: 600; + color: var(--text-dark); white-space: nowrap; - padding-right: 20px; - width: 20em; + padding-right: 2rem; + width: 280px; } -tr { - margin-top: 10px; +.value { + color: var(--text-gray); + font-family: 'Monaco', 'Menlo', 'Courier New', monospace; } -pre { +.value pre { white-space: pre-wrap; word-break: break-all; + margin: 0; } -.message { - color: green; - padding: 20px; - margin-left: -22px; - font-size: 16px; - font-weight: 500; - border: 2px solid green; - border-radius: 5px; +/* Tooltip Styles - Matching Self-Serve Portal */ +.tooltip-wrapper { + display: inline-flex; + align-items: center; + gap: 0.5rem; } -#verification_instructions { - margin-top: 20px; - margin-bottom: 30px; - padding: 15px; - background-color: #f5f5f5; - border-left: 4px solid #4CAF50; - line-height: 1.6; +.tooltip { + position: relative; + display: inline-flex; + align-items: center; + cursor: help; } -#page-content { - position: relative; - max-width: 640px; - margin: 10px 0; +.tooltip-trigger { + width: 16px; + height: 16px; + border-radius: 50%; + background-color: var(--tooltip-trigger); + color: white; + border: none; + font-size: 0.7rem; + font-weight: 700; + display: flex; + align-items: center; + justify-content: center; + cursor: help; + transition: all 0.2s ease; + flex-shrink: 0; } -#video-container { - position: relative; - padding-bottom: 56.25%; +.tooltip-trigger:hover { + background-color: var(--tooltip-trigger-hover); + transform: scale(1.05); } -#video-element { +.tooltip-content { + visibility: hidden; + opacity: 0; position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; + bottom: calc(100% + 8px); + left: 50%; + transform: translateX(-50%); + background-color: var(--tooltip-bg); + color: white; + padding: 10px; + border-radius: 4px; + font-size: 0.75rem; + line-height: 1.125; + min-width: 300px; + max-width: 570px; + white-space: normal; + z-index: 10000; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + transition: opacity 0.2s ease, visibility 0.2s ease; + font-weight: 400; + pointer-events: none; } -#ad-container { +.tooltip-content::after { + content: ""; position: absolute; - top: 0; - left: 0; + top: 100%; + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: var(--tooltip-bg) transparent transparent transparent; +} + +.tooltip:hover .tooltip-content { + visibility: visible; + opacity: 1; +} + +/* Forms */ +.form { + margin-top: 2rem; +} + +.email_prompt { + display: flex; + gap: 0; + max-width: 600px; + box-shadow: var(--shadow); + border-radius: 8px; + overflow: hidden; +} + +#email { + flex: 1; + padding: 0.875rem 1.25rem; + border: 2px solid var(--border-color); + border-right: none; + font-size: 0.95rem; + color: var(--text-dark); + outline: none; + transition: border-color 0.2s ease; +} + +#email:focus { + border-color: var(--primary-orange); +} + +#email::placeholder { + color: var(--text-gray); +} + +/* Buttons */ +.button { + padding: 0.875rem 2rem; + background: var(--button-navy); + color: white; + border: none; + font-size: 0.95rem; + font-weight: 700; + cursor: pointer; + transition: all 0.2s ease; + white-space: nowrap; + box-shadow: var(--shadow); +} + +.button:hover { + background: var(--button-navy-hover); + transform: translateY(-2px); + box-shadow: 0 6px 12px rgba(2, 10, 64, 0.3); +} + +.button:active { + transform: translateY(0); +} + +/* Full width button for logout */ +#clear_storage_form .button { width: 100%; - height: 100%; + max-width: 600px; + border-radius: 8px; } -#integration_state { - margin-top: 20px; +/* Verification Instructions */ +#verification_instructions { + background: linear-gradient(135deg, rgba(13, 148, 136, 0.1) 0%, rgba(13, 148, 136, 0.05) 100%); + border-left: 4px solid var(--accent-teal); + padding: 1.25rem; + margin: 1.5rem 0; + border-radius: 6px; + font-size: 0.9rem; + line-height: 1.7; + color: var(--text-dark); } -#integration_state .label { - min-width: 20em; - width: 20em; - vertical-align: top; +/* Success Message */ +.message { + background: linear-gradient(135deg, rgba(34, 197, 94, 0.1) 0%, rgba(34, 197, 94, 0.05) 100%); + border-left: 4px solid #22C55E; + color: #15803D; + padding: 1.25rem; + margin: 1.5rem 0; + font-size: 0.95rem; + font-weight: 600; + border-radius: 6px; } +/* Responsive Design */ +@media (max-width: 1024px) { + .page-wrapper { + flex-direction: column; + } + + .sidebar { + position: static; + max-height: none; + order: -1; /* Put sidebar on top on mobile */ + } + + body { + padding: 1rem; + } + + .main-content { + padding: 1.5rem; + } + + h1 { + font-size: 1.5rem; + } + + h2 { + font-size: 1.25rem; + } + + .email_prompt { + flex-direction: column; + } + + #email { + border-right: 2px solid var(--border-color); + border-bottom: none; + } + + .button { + width: 100%; + } +} diff --git a/web-integrations/prebid-secure-signals/client-side/index.html b/web-integrations/prebid-secure-signals/client-side/index.html index 52de962..f45f68a 100644 --- a/web-integrations/prebid-secure-signals/client-side/index.html +++ b/web-integrations/prebid-secure-signals/client-side/index.html @@ -47,9 +47,6 @@ // Show "undefined" if no token, otherwise show the token $('#advertising_token').text(identity ? String(identity.id) : 'undefined'); - // Update the label to include the storage key name - $('#prebid_storage_label').text(`Prebid Token Storage ('${UID_STORAGE_KEY}' in localStorage):`); - // Show localStorage content with formatted structure const localStorageValue = localStorage.getItem(storageKey); if (localStorageValue) { @@ -260,42 +257,89 @@ -

Client-Side ${IDENTITY_NAME} Integration with Prebid.js and Google Secure Signals

+
+ +
+

Client-Side ${IDENTITY_NAME} Integration with Prebid.js and Google Secure Signals

This example demonstrates how a content publisher can integrate ${IDENTITY_NAME} with both Prebid.js (for header bidding) and Google Secure Signals (for Google Ad Manager), using client-side token generation. Prebid manages the ${IDENTITY_NAME} token, - and Google Secure Signals reads from Prebid's storage automatically. For documentation, see: -

- Note: This is a test-only integration environment—not for production use. - It does not perform real user authentication or generate production-level tokens. - Do not use real user data on this page. + and Google Secure Signals reads from Prebid's storage automatically. For documentation, see ${IDENTITY_NAME} Client-Side Integration Guide for Prebid.js + and Google Ad Manager Secure Signals Integration Guide for more details.

${IDENTITY_NAME} Integration Status

- + - + - + - + - +
Ready for Targeted Advertising: +
+ Ready for Targeted Advertising: +
+ ? +
+ Indicates whether a valid ${IDENTITY_NAME} token is available. Returns "yes" when Prebid has successfully generated and stored a token. +
+
+
+
${IDENTITY_NAME} Advertising Token (from Prebid): +
+ Advertising Token: +
+ ? +
+ The ${IDENTITY_NAME} token used for targeted advertising. This token is passed to the bidstream and automatically refreshed by the SDK in the background when expired. +
+
+
+
Is ${IDENTITY_NAME} Login Required? +
+ Is Login Required? +
+ ? +
+ Indicates whether a new ${IDENTITY_NAME} token needs to be generated. Returns "yes" when no valid identity exists or the current identity has expired. +
+
+
+
Prebid Token Storage: +
+ Prebid Token Storage: +
+ ? +
+ Shows the ${IDENTITY_NAME} token stored by Prebid in localStorage under the key '${UID_STORAGE_KEY}'. This storage is shared between Prebid and Google Secure Signals. +
+
+
+
Secure Signals Configured via Prebid? +
+ Secure Signals Configured? +
+ ? +
+ Indicates whether Google Secure Signals integration is properly configured in Prebid. When "yes", encrypted ${IDENTITY_NAME} signals are sent to Google Ad Manager. +
+
+
+
@@ -320,15 +364,59 @@

${IDENTITY_NAME} Integration Status

id="email" name="email" placeholder="Enter an email address" - style="border-style: none" /> + -
+ + + + diff --git a/web-integrations/styles/themes.css b/web-integrations/styles/colors.css similarity index 66% rename from web-integrations/styles/themes.css rename to web-integrations/styles/colors.css index ce97fa2..43b3c9c 100644 --- a/web-integrations/styles/themes.css +++ b/web-integrations/styles/colors.css @@ -1,10 +1,8 @@ /* - * Centralized UID2 Examples Theme Variables + * Centralized UID2 Examples Color Variables * - * This file defines the color palette and design tokens used across all UID2 example sites. - * To use in your site, either: - * 1. Link this file in your HTML: - * 2. Copy these :root variables into your site's CSS file + * This file defines all colors used across UID2 example sites. + * Import this file in your CSS: @import url('path/to/colors.css'); */ :root { @@ -31,8 +29,8 @@ --button-navy-hover: rgba(2, 10, 64, 0.9); /* Link Colors */ - --link-color: #0459fd; - --link-hover: #0347cc; + --link-color: #06B6D4; + --link-hover: #06B6D4; /* Tooltip Colors */ --tooltip-bg: #1F2937; diff --git a/web-integrations/styles/colors.scss b/web-integrations/styles/colors.scss deleted file mode 100644 index a841c4a..0000000 --- a/web-integrations/styles/colors.scss +++ /dev/null @@ -1,31 +0,0 @@ -// Brand Colors -$color-primary-orange: #FF6B35; -$color-primary-dark: #2D3748; -$color-accent-teal: #0D9488; -$color-accent-yellow: #FBBF24; - -// Text Colors -$color-text-dark: #1A202C; -$color-text-gray: #718096; - -// Background Colors -$color-bg-white: #FFFFFF; -$color-bg-light: #F7FAFC; -$color-sidebar-bg: #FFF7ED; - -// Border & Shadow Colors -$color-border: #E2E8F0; - -// Button Colors -$color-button-navy: rgba(2, 10, 64, 1); -$color-button-navy-hover: rgba(2, 10, 64, 0.9); - -// Link Colors -$color-link: #0459fd; -$color-link-hover: #0347cc; - -// Tooltip Colors -$color-tooltip-bg: #1F2937; -$color-tooltip-trigger: #3B82F6; -$color-tooltip-trigger-hover: #2563EB; - diff --git a/web-integrations/styles/themes.scss b/web-integrations/styles/themes.scss deleted file mode 100644 index 96de43a..0000000 --- a/web-integrations/styles/themes.scss +++ /dev/null @@ -1,39 +0,0 @@ -@use "colors" as *; - -:root { - /* Brand Colors */ - --primary-orange: #{$color-primary-orange}; - --primary-dark: #{$color-primary-dark}; - --accent-teal: #{$color-accent-teal}; - --accent-yellow: #{$color-accent-yellow}; - - /* Text Colors */ - --text-dark: #{$color-text-dark}; - --text-gray: #{$color-text-gray}; - - /* Background Colors */ - --bg-white: #{$color-bg-white}; - --bg-light: #{$color-bg-light}; - --sidebar-bg: #{$color-sidebar-bg}; - - /* Border Colors */ - --border-color: #{$color-border}; - - /* Button Colors */ - --button-navy: #{$color-button-navy}; - --button-navy-hover: #{$color-button-navy-hover}; - - /* Link Colors */ - --link-color: #{$color-link}; - --link-hover: #{$color-link-hover}; - - /* Tooltip Colors */ - --tooltip-bg: #{$color-tooltip-bg}; - --tooltip-trigger: #{$color-tooltip-trigger}; - --tooltip-trigger-hover: #{$color-tooltip-trigger-hover}; - - /* Shadows */ - --shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); - --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1); -} - From b42319550beff8428df142e931ffa74fd74542cb Mon Sep 17 00:00:00 2001 From: Eiman Eltigani Date: Tue, 25 Nov 2025 10:49:24 -0500 Subject: [PATCH 05/11] update other client-side site design --- .../client-side/Dockerfile | 3 + .../client-side/html/index.html | 251 +++++++--- .../client-side/html/styles/app.css | 462 ++++++++++++++---- .../client-side/html/index.html | 6 +- .../client-side/Dockerfile | 3 + .../prebid-integrations/client-side/app.css | 414 +++++++++++++--- .../client-side/index.html | 187 +++++-- 7 files changed, 1046 insertions(+), 280 deletions(-) diff --git a/web-integrations/google-secure-signals/client-side/Dockerfile b/web-integrations/google-secure-signals/client-side/Dockerfile index 1cf6516..2b3bb4e 100644 --- a/web-integrations/google-secure-signals/client-side/Dockerfile +++ b/web-integrations/google-secure-signals/client-side/Dockerfile @@ -6,6 +6,9 @@ RUN apk add --no-cache gettext # Copy static files from client-side directory COPY web-integrations/google-secure-signals/client-side/html /usr/share/nginx/html/ +# Copy shared styles folder +COPY web-integrations/styles /usr/share/nginx/html/styles/ + # Copy config and entrypoint COPY web-integrations/google-secure-signals/client-side/default.conf /etc/nginx/conf.d/default.conf COPY web-integrations/google-secure-signals/client-side/entrypoint.sh /entrypoint.sh diff --git a/web-integrations/google-secure-signals/client-side/html/index.html b/web-integrations/google-secure-signals/client-side/html/index.html index 249a3b4..515e08d 100644 --- a/web-integrations/google-secure-signals/client-side/html/index.html +++ b/web-integrations/google-secure-signals/client-side/html/index.html @@ -12,76 +12,189 @@ -

Client-Side ${IDENTITY_NAME} SDK Integration Example with Google Secure Signals

-

- This example demonstrates how a content publisher can follow the - Client-Side Integration Guide for JavaScript to implement ${IDENTITY_NAME} integration and generate ${IDENTITY_NAME} tokens. - Secure Signals is updated when the page is reloaded. - Reload the page in order to update Secure Signals in local storage. - Note: This is a test-only integration environment—not for production use. - It does not perform real user authentication or generate production-level tokens. - Do not use real user data on this page. -

-
-
- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - -
Ready for Targeted Advertising:
${IDENTITY_NAME} Advertising Token:
Is ${IDENTITY_NAME} Login Required?
${IDENTITY_NAME} Identity Callback State:
Secure Signals Loaded?
Secure Signals Value:
-
- - -
- Note: This is a test-only environment. Do not use real user data. The integration demonstrates client-side token generation with Google Secure Signals. + Note: This is a test-only environment. Do not use real user data.
diff --git a/web-integrations/javascript-sdk/client-side/html/index.html b/web-integrations/javascript-sdk/client-side/html/index.html index cd66509..5f4ce2f 100644 --- a/web-integrations/javascript-sdk/client-side/html/index.html +++ b/web-integrations/javascript-sdk/client-side/html/index.html @@ -98,7 +98,7 @@

${IDENTITY_NAME} Integration Status

?
- Indicates whether a valid advertising token is available for use in targeted advertising. Returns "yes" when the SDK has successfully generated or refreshed a token. + Indicates whether a valid ${IDENTITY_NAME} token is present and can be used for personalized ad targeting.
@@ -112,7 +112,7 @@

${IDENTITY_NAME} Integration Status

?
- This token is passed to the bidstream and used for targeted advertising. It is automatically refreshed by the SDK in the background when expired. + The encrypted ${IDENTITY_NAME} token passed to ad systems without exposing raw user identity. It is automatically refreshed by the SDK in the background when expired.
@@ -140,7 +140,7 @@

${IDENTITY_NAME} Integration Status

?
- Indicates whether the user has opted out of ${IDENTITY_NAME}. When "yes", no advertising token will be generated and targeted advertising should not be enabled. + Shows whether the user has exercised opt-out, in which case no advertising token may be generated or used.
@@ -154,7 +154,7 @@

${IDENTITY_NAME} Integration Status

?
- The complete identity object returned by the SDK. Contains the full ${IDENTITY_NAME} identity data including refresh tokens and metadata. Used for debugging and verification. + The complete identity object returned by the SDK. Contains the full ${IDENTITY_NAME} identity data including refresh tokens and metadata.
@@ -228,7 +228,7 @@

What's Happening?

- Note: This is a test-only environment. Do not use real user data. The integration uses Client-Side Token Generation (CSTG) with public credentials. + Note: This is a test-only environment. Do not use real user data.
diff --git a/web-integrations/prebid-integrations/client-side/index.html b/web-integrations/prebid-integrations/client-side/index.html index aa017b8..0d0a736 100644 --- a/web-integrations/prebid-integrations/client-side/index.html +++ b/web-integrations/prebid-integrations/client-side/index.html @@ -210,8 +210,7 @@

${IDENTITY_NAME} Integration Status

?
- Indicates whether a valid ${IDENTITY_NAME} token is available. Returns "yes" when Prebid has successfully generated and stored a token. -
+ Indicates whether a valid ${IDENTITY_NAME} token is present and can be used for personalized ad targeting.
@@ -224,7 +223,7 @@

${IDENTITY_NAME} Integration Status

?
- The ${IDENTITY_NAME} token used for targeted advertising. This token is passed to the bidstream and automatically refreshed by the SDK in the background when expired. + The encrypted ${IDENTITY_NAME} token passed to ad systems without exposing raw user identity. It is automatically refreshed by the SDK in the background when expired.
@@ -320,7 +319,7 @@

What's Happening?

- Note: This is a test-only environment. Do not use real user data. The integration demonstrates client-side token generation for header bidding. + Note: This is a test-only environment. Do not use real user data.
diff --git a/web-integrations/prebid-secure-signals/client-side/index.html b/web-integrations/prebid-secure-signals/client-side/index.html index f45f68a..2711f33 100644 --- a/web-integrations/prebid-secure-signals/client-side/index.html +++ b/web-integrations/prebid-secure-signals/client-side/index.html @@ -279,7 +279,7 @@

${IDENTITY_NAME} Integration Status

?
- Indicates whether a valid ${IDENTITY_NAME} token is available. Returns "yes" when Prebid has successfully generated and stored a token. + Indicates whether a valid ${IDENTITY_NAME} token is present and can be used for personalized ad targeting.
@@ -293,7 +293,7 @@

${IDENTITY_NAME} Integration Status

?
- The ${IDENTITY_NAME} token used for targeted advertising. This token is passed to the bidstream and automatically refreshed by the SDK in the background when expired. + The encrypted ${IDENTITY_NAME} token passed to ad systems without exposing raw user identity. It is automatically refreshed by the SDK in the background when expired.
@@ -414,7 +414,7 @@

What's Happening?

- Note: This is a test-only environment. Do not use real user data. The integration demonstrates client-side token generation and sharing. + Note: This is a test-only environment. Do not use real user data.
From 7c31d1d3b1797ff944ddd2e29c367fe17e566ee1 Mon Sep 17 00:00:00 2001 From: Eiman Eltigani Date: Tue, 25 Nov 2025 15:59:15 -0500 Subject: [PATCH 07/11] fix tooltip display bug and syncing bug for prebid secure signals site --- .../google-secure-signals/client-side/html/styles/app.css | 2 ++ web-integrations/prebid-integrations/client-side/app.css | 2 ++ .../prebid-integrations/client-side/index.html | 7 ++++++- web-integrations/prebid-secure-signals/client-side/app.css | 2 ++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/web-integrations/google-secure-signals/client-side/html/styles/app.css b/web-integrations/google-secure-signals/client-side/html/styles/app.css index a018dda..c8aa182 100644 --- a/web-integrations/google-secure-signals/client-side/html/styles/app.css +++ b/web-integrations/google-secure-signals/client-side/html/styles/app.css @@ -137,6 +137,8 @@ a:hover { border-radius: 8px; overflow: hidden; font-size: 0.875rem; + position: relative; + overflow: visible; } #uid2_state tr { diff --git a/web-integrations/prebid-integrations/client-side/app.css b/web-integrations/prebid-integrations/client-side/app.css index 0c351ec..a844c99 100644 --- a/web-integrations/prebid-integrations/client-side/app.css +++ b/web-integrations/prebid-integrations/client-side/app.css @@ -137,6 +137,8 @@ a:hover { border-radius: 8px; overflow: hidden; font-size: 0.875rem; + position: relative; + overflow: visible; } #identity_state tr { diff --git a/web-integrations/prebid-integrations/client-side/index.html b/web-integrations/prebid-integrations/client-side/index.html index 0d0a736..0d4ce13 100644 --- a/web-integrations/prebid-integrations/client-side/index.html +++ b/web-integrations/prebid-integrations/client-side/index.html @@ -85,7 +85,12 @@ $('#login').click(handleLogin); $('#clear_storage').click(handleClearStorage); - updateGuiElements(); + // Wait for Prebid to load user IDs from storage before updating UI + pbjs.que.push(function() { + pbjs.onEvent('userIds', updateGuiElements); + // Also update immediately in case IDs are already loaded + updateGuiElements(); + }); } function setUidConfig(email) { diff --git a/web-integrations/prebid-secure-signals/client-side/app.css b/web-integrations/prebid-secure-signals/client-side/app.css index 9611f3d..facb4f0 100644 --- a/web-integrations/prebid-secure-signals/client-side/app.css +++ b/web-integrations/prebid-secure-signals/client-side/app.css @@ -139,6 +139,8 @@ a:hover { border-radius: 8px; overflow: hidden; font-size: 0.875rem; + position: relative; + overflow: visible; } #integration_state tr { From 4a5998a88c4f797c36e390e93ce8cf4fee008372 Mon Sep 17 00:00:00 2001 From: Eiman Eltigani Date: Tue, 25 Nov 2025 16:48:11 -0500 Subject: [PATCH 08/11] update and standardize opt out testing steps based off integration --- .../client-side/html/index.html | 27 ++++++++----- .../client-side/html/scripts/scripts.js | 18 +-------- .../client-side/html/styles/app.css | 15 ------- .../client-side/html/index.html | 4 +- .../client-side/index.html | 14 +++---- .../client-side/index.html | 40 +++++++++++++++++-- 6 files changed, 65 insertions(+), 53 deletions(-) diff --git a/web-integrations/google-secure-signals/client-side/html/index.html b/web-integrations/google-secure-signals/client-side/html/index.html index 4bf99e8..72ae6c2 100644 --- a/web-integrations/google-secure-signals/client-side/html/index.html +++ b/web-integrations/google-secure-signals/client-side/html/index.html @@ -65,6 +65,20 @@

${IDENTITY_NAME} Integration Status


           
+          
+            
+              
+ Has Opted Out? +
+ ? +
+ Shows whether the user has exercised opt-out, in which case no advertising token may be generated or used. +
+
+
+ +

+          
           
             
               
@@ -120,12 +134,6 @@

${IDENTITY_NAME} Integration Status

- - diff --git a/web-integrations/prebid-integrations/client-side/index.html b/web-integrations/prebid-integrations/client-side/index.html index 2be40a3..263ce92 100644 --- a/web-integrations/prebid-integrations/client-side/index.html +++ b/web-integrations/prebid-integrations/client-side/index.html @@ -228,7 +228,7 @@

${IDENTITY_NAME} Integration Status

?
- The encrypted ${IDENTITY_NAME} token passed to ad systems without exposing raw user identity. It is automatically refreshed by the SDK in the background when expired. + The encrypted ${IDENTITY_NAME} token that is passed to ad systems without exposing raw user identity. It is automatically refreshed by the SDK in the background when expired.
diff --git a/web-integrations/prebid-secure-signals/client-side/index.html b/web-integrations/prebid-secure-signals/client-side/index.html index 1ed3937..58dc793 100644 --- a/web-integrations/prebid-secure-signals/client-side/index.html +++ b/web-integrations/prebid-secure-signals/client-side/index.html @@ -313,7 +313,7 @@

${IDENTITY_NAME} Integration Status

?
- The encrypted ${IDENTITY_NAME} token passed to ad systems without exposing raw user identity. It is automatically refreshed by the SDK in the background when expired. + The encrypted ${IDENTITY_NAME} token that is passed to ad systems without exposing raw user identity. It is automatically refreshed by the SDK in the background when expired.
From ea3296ce1b05171c5aa301ed0d37dc05f6463d33 Mon Sep 17 00:00:00 2001 From: Eiman Eltigani Date: Tue, 25 Nov 2025 17:32:08 -0500 Subject: [PATCH 11/11] clarify whats happening in secure signals sample page for extra clarity --- .../google-secure-signals/client-side/html/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web-integrations/google-secure-signals/client-side/html/index.html b/web-integrations/google-secure-signals/client-side/html/index.html index 99f5758..a287880 100644 --- a/web-integrations/google-secure-signals/client-side/html/index.html +++ b/web-integrations/google-secure-signals/client-side/html/index.html @@ -195,7 +195,8 @@

What's Happening?

  • Client-Side Token Generation: The SDK generates tokens directly in the browser
  • Auto-Refresh: Tokens are automatically refreshed by the SDK in the background when expired
  • -
  • Google Secure Signals: Encrypted tokens are stored and shared with Google Ad Manager
  • +
  • Local Storage: The SDK stores identity in localStorage (__uid2_advertising_token or __euid_advertising_token) for persistence across page loads
  • +
  • Google Secure Signals: Encrypted tokens are stored in localStorage under ${UID_SECURE_SIGNALS_STORAGE_KEY} and shared with Google Ad Manager
  • IMA SDK: Displays video ads with ${IDENTITY_NAME} targeting