Skip to content

Commit b92ba10

Browse files
Merge pull request #135 from IABTechLab/eee-UID2-5808-modernize-ui-react-examples
Update design for both react sites
2 parents 81640f1 + 33f6b32 commit b92ba10

File tree

4 files changed

+1126
-334
lines changed

4 files changed

+1126
-334
lines changed

web-integrations/google-secure-signals/react-client-side/src/SecureSignalsApp.tsx

Lines changed: 195 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ const SecureSignalsApp = () => {
114114

115115
const onIdentityUpdated = useCallback(
116116
(eventType, payload) => {
117-
console.log(`${IDENTITY_NAME} Callback`, payload);
117+
console.log(`${IDENTITY_NAME} Callback`, payload);
118118
updateElements(payload);
119119
},
120120
[updateElements]
@@ -382,119 +382,241 @@ const SecureSignalsApp = () => {
382382
};
383383

384384
return (
385-
<div>
386-
<h1>
387-
React Client-Side {IDENTITY_NAME} SDK Integration Example with Google Secure Signals
388-
</h1>
389-
<p>
390-
This example demonstrates how a content publisher can follow the{' '}
391-
<a href={`${DOCS_BASE_URL}/guides/integration-javascript-client-side`}>
392-
Client-Side Integration Guide for JavaScript
393-
</a>{' '}
394-
to implement {IDENTITY_NAME} integration and generate {IDENTITY_NAME} tokens. Secure Signals is updated when the
395-
page is reloaded. Reload the page in order to update Secure Signals in local storage.
396-
</p>
397-
398-
<div id='page-content'>
399-
<div id='video-container'>
400-
<video id='video-element' ref={videoElementRef} onClick={handlePlay}>
401-
<source src='https://storage.googleapis.com/interactive-media-ads/media/android.mp4' />
402-
<source src='https://storage.googleapis.com/interactive-media-ads/media/android.webm' />
403-
</video>
404-
<div id='ad-container' ref={adContainerRef} onClick={handleAdContainerClick}></div>
385+
<div className="page-wrapper">
386+
<div className="main-content">
387+
<h1>
388+
React Client-Side {IDENTITY_NAME} SDK Integration Example with Google Secure Signals
389+
</h1>
390+
<p>
391+
This example demonstrates how a content publisher can integrate {IDENTITY_NAME} with Google Secure Signals using client-side token generation with React, where the SDK generates tokens directly in the browser. For documentation, see the{' '}
392+
<a href={`${DOCS_BASE_URL}/guides/integration-javascript-client-side`}>
393+
Client-Side Integration Guide for JavaScript
394+
</a>{' '}
395+
and{' '}
396+
<a href={`${DOCS_BASE_URL}/guides/integration-google-ss`}>
397+
Google Ad Manager Secure Signals Integration Guide
398+
</a>.
399+
</p>
400+
401+
<div id='page-content'>
402+
<div id='video-container'>
403+
<video id='video-element' ref={videoElementRef} onClick={handlePlay}>
404+
<source src='https://storage.googleapis.com/interactive-media-ads/media/android.mp4' />
405+
<source src='https://storage.googleapis.com/interactive-media-ads/media/android.webm' />
406+
</video>
407+
<div id='ad-container' ref={adContainerRef} onClick={handleAdContainerClick}></div>
408+
</div>
409+
<button id='play-button' onClick={handlePlay}>
410+
Play
411+
</button>
405412
</div>
406-
<button id='play-button' onClick={handlePlay}>
407-
Play
408-
</button>
409-
</div>
410413

411-
<div className='product-tables'>
412-
<table id='uid2_state'>
413-
<thead>
414-
<tr>
415-
<th>{IDENTITY_NAME} Status</th>
416-
</tr>
417-
</thead>
414+
<h2>{IDENTITY_NAME} Integration Status</h2>
415+
<table id='uid_state'>
418416
<tbody>
419417
<tr>
420-
<td className='label'>Ready for Targeted Advertising:</td>
418+
<td className='label'>
419+
<div className="tooltip-wrapper">
420+
Ready for Targeted Advertising:
421+
<div className="tooltip">
422+
<span className="tooltip-trigger">?</span>
423+
<div className="tooltip-content">
424+
Indicates whether a valid {IDENTITY_NAME} token is present and can be passed to Google Secure Signals for targeted advertising.
425+
</div>
426+
</div>
427+
</div>
428+
</td>
421429
<td className='value'>
422430
<pre>{targetedAdvertisingReady ? 'yes' : 'no'}</pre>
423431
</td>
424432
</tr>
425433
<tr>
426-
<td className='label'>{IDENTITY_NAME} Advertising Token:</td>
434+
<td className='label'>
435+
<div className="tooltip-wrapper">
436+
Advertising Token:
437+
<div className="tooltip">
438+
<span className="tooltip-trigger">?</span>
439+
<div className="tooltip-content">
440+
The encrypted {IDENTITY_NAME} token passed to Google Secure Signals for advertising. It is automatically refreshed by the SDK in the background when expired.
441+
</div>
442+
</div>
443+
</div>
444+
</td>
427445
<td className='value'>
428446
<pre>{advertisingToken}</pre>
429447
</td>
430448
</tr>
431449
<tr>
432-
<td className='label'>Is {IDENTITY_NAME} Login Required?</td>
450+
<td className='label'>
451+
<div className="tooltip-wrapper">
452+
Is Login Required?
453+
<div className="tooltip">
454+
<span className="tooltip-trigger">?</span>
455+
<div className="tooltip-content">
456+
Indicates whether a new {IDENTITY_NAME} token needs to be generated. Returns "yes" when no valid identity exists or the current identity has expired.
457+
</div>
458+
</div>
459+
</div>
460+
</td>
433461
<td className='value'>
434462
<pre>{loginRequired ? 'yes' : 'no'}</pre>
435463
</td>
436464
</tr>
437465
<tr>
438-
<td className='label'>{IDENTITY_NAME} Identity Callback State:</td>
466+
<td className='label'>
467+
<div className="tooltip-wrapper">
468+
Has opted out?
469+
<div className="tooltip">
470+
<span className="tooltip-trigger">?</span>
471+
<div className="tooltip-content">
472+
Shows whether the user has exercised opt-out, in which case no advertising token may be generated or used.
473+
</div>
474+
</div>
475+
</div>
476+
</td>
477+
<td className='value'>
478+
<pre>{isOptedOut ? 'yes' : 'no'}</pre>
479+
</td>
480+
</tr>
481+
<tr>
482+
<td className='label'>
483+
<div className="tooltip-wrapper">
484+
Identity Callback State:
485+
<div className="tooltip">
486+
<span className="tooltip-trigger">?</span>
487+
<div className="tooltip-content">
488+
The complete identity object returned by the SDK. Contains the full {IDENTITY_NAME} identity data including refresh tokens and metadata.
489+
</div>
490+
</div>
491+
</div>
492+
</td>
439493
<td className='value'>
440494
<pre>{identityState}</pre>
441495
</td>
442496
</tr>
443497
<tr>
444-
<td className='label'>Secure Signals Loaded?</td>
498+
<td className='label'>
499+
<div className="tooltip-wrapper">
500+
Secure Signals Loaded?
501+
<div className="tooltip">
502+
<span className="tooltip-trigger">?</span>
503+
<div className="tooltip-content">
504+
Indicates whether Google Secure Signals has successfully loaded and cached the {IDENTITY_NAME} token.
505+
</div>
506+
</div>
507+
</div>
508+
</td>
445509
<td className='value'>
446510
<pre>{secureSignalsLoaded ? 'yes' : 'no'}</pre>
447511
</td>
448512
</tr>
449513
<tr>
450-
<td className='label'>Secure Signals Value:</td>
514+
<td className='label'>
515+
<div className="tooltip-wrapper">
516+
Secure Signals Value:
517+
<div className="tooltip">
518+
<span className="tooltip-trigger">?</span>
519+
<div className="tooltip-content">
520+
The {IDENTITY_NAME} data stored by Google Secure Signals in local storage for use in ad requests.
521+
</div>
522+
</div>
523+
</div>
524+
</td>
451525
<td className='value'>
452526
<pre>{secureSignalsValue}</pre>
453527
</td>
454528
</tr>
455529
</tbody>
456530
</table>
457-
</div>
458531

459-
{isOptedOut ? (
460-
<>
461-
<div id='optout_banner' style={{ border: '3px solid #ffc107', padding: '15px', margin: '20px 0' }}>
462-
<p style={{ margin: 0 }}>The email address you entered has opted out of {IDENTITY_NAME}.</p>
532+
{isOptedOut ? (
533+
<>
534+
<div id='optout_banner' style={{ border: '3px solid #ffc107', padding: '15px', margin: '20px 0' }}>
535+
<p style={{ margin: 0 }}>The email address you entered has opted out of {IDENTITY_NAME}.</p>
536+
</div>
537+
<div id='optout_message' className='form'>
538+
<button type='button' className='button' onClick={handleTryAnother}>
539+
Try Another Email
540+
</button>
541+
</div>
542+
</>
543+
) : !isLoggedIn ? (
544+
<div id='login_form' className='form'>
545+
<div className='email_prompt'>
546+
<input
547+
type='text'
548+
id='email'
549+
name='email'
550+
placeholder='Enter an email address'
551+
value={email}
552+
onChange={handleEmailChange}
553+
/>
554+
<button type='button' className='button' onClick={handleLogin}>
555+
Generate {IDENTITY_NAME}
556+
</button>
557+
</div>
463558
</div>
464-
<div id='optout_message' className='form'>
465-
<button type='button' className='button' onClick={handleTryAnother}>
466-
Try Another Email
467-
</button>
468-
</div>
469-
</>
470-
) : !isLoggedIn ? (
471-
<div id='login_form' className='form'>
472-
<div className='email_prompt'>
473-
<input
474-
type='text'
475-
id='email'
476-
name='email'
477-
placeholder='Enter an email address'
478-
style={{ borderStyle: 'none' }}
479-
value={email}
480-
onChange={handleEmailChange}
481-
/>
482-
</div>
483-
<div>
484-
<button type='button' className='button' onClick={handleLogin}>
485-
Generate {IDENTITY_NAME}
559+
) : (
560+
<div id='logout_form' className='form'>
561+
<button type='button' className='button' onClick={handleLogout}>
562+
Clear {IDENTITY_NAME}
486563
</button>
487564
</div>
565+
)}
566+
</div>
567+
568+
<aside className="sidebar">
569+
<h3>📋 How to Test</h3>
570+
571+
<div className="section">
572+
<h4>Step 1: Generate {IDENTITY_NAME}</h4>
573+
<ul>
574+
<li>Enter an email address in the input field</li>
575+
<li>Click "Generate {IDENTITY_NAME}" button</li>
576+
<li>The SDK will initialize and request a token</li>
577+
</ul>
488578
</div>
489-
) : (
490-
<div id='logout_form' className='form'>
491-
<form>
492-
<button type='button' className='button' onClick={handleLogout}>
493-
Clear {IDENTITY_NAME}
494-
</button>
495-
</form>
579+
580+
<div className="section">
581+
<h4>Step 2: View Video Ad</h4>
582+
<ul>
583+
<li>Click the "Play" button to start the video</li>
584+
<li>Google Secure Signals will use the {IDENTITY_NAME} token</li>
585+
<li>Observe ad targeting with {IDENTITY_NAME}</li>
586+
</ul>
587+
</div>
588+
589+
<div className="section">
590+
<h4>Step 3: Verify Secure Signals</h4>
591+
<ul>
592+
<li>Check "Secure Signals Loaded?" changes to "yes"</li>
593+
<li>View the Secure Signals value in the table</li>
594+
<li>Token is stored in localStorage for ad requests</li>
595+
</ul>
596+
</div>
597+
598+
<div className="section">
599+
<h4>Step 4: Test Opt-Out</h4>
600+
<ul>
601+
<li>Clear {IDENTITY_NAME}, then try: <strong>[email protected]</strong></li>
602+
<li>Observe "Has opted out?" changes to "yes"</li>
603+
<li>No advertising token or Secure Signals are generated</li>
604+
</ul>
605+
</div>
606+
607+
<div className="section">
608+
<h4>What's Happening?</h4>
609+
<ul>
610+
<li><strong>Client-Side Token Generation:</strong> The SDK generates tokens directly in the browser using your public credentials</li>
611+
<li><strong>Secure Signals Integration:</strong> Google Secure Signals automatically retrieves and caches the {IDENTITY_NAME} token</li>
612+
<li><strong>Local Storage:</strong> Both SDK identity and Secure Signals data are stored in localStorage for persistence</li>
613+
</ul>
614+
</div>
615+
616+
<div className="note">
617+
<strong>Note:</strong> This is a test-only environment. Do not use real user data.
496618
</div>
497-
)}
619+
</aside>
498620
</div>
499621
);
500622
};

0 commit comments

Comments
 (0)