@@ -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