@@ -82,7 +82,7 @@ const SecureSignalsApp = () => {
8282
8383 const onIdentityUpdated = useCallback (
8484 ( eventType , payload ) => {
85- console . log ( `${ IDENTITY_NAME } Callback` , payload ) ;
85+ console . log ( `${ IDENTITY_NAME } Callback` , payload ) ;
8686 updateElements ( payload ) ;
8787 } ,
8888 [ updateElements ]
@@ -307,119 +307,241 @@ const SecureSignalsApp = () => {
307307 } ;
308308
309309 return (
310- < div >
311- < h1 >
312- React Client-Side { IDENTITY_NAME } SDK Integration Example with Google Secure Signals
313- </ h1 >
314- < p >
315- This example demonstrates how a content publisher can follow the{ ' ' }
316- < a href = { `${ DOCS_BASE_URL } /guides/integration-javascript-client-side` } >
317- Client-Side Integration Guide for JavaScript
318- </ a > { ' ' }
319- to implement { IDENTITY_NAME } integration and generate { IDENTITY_NAME } tokens. Secure Signals is updated when the
320- page is reloaded. Reload the page in order to update Secure Signals in local storage.
321- </ p >
322-
323- < div id = 'page-content' >
324- < div id = 'video-container' >
325- < video id = 'video-element' ref = { videoElementRef } onClick = { handlePlay } >
326- < source src = 'https://storage.googleapis.com/interactive-media-ads/media/android.mp4' />
327- < source src = 'https://storage.googleapis.com/interactive-media-ads/media/android.webm' />
328- </ video >
329- < div id = 'ad-container' ref = { adContainerRef } onClick = { handleAdContainerClick } > </ div >
310+ < div className = "page-wrapper" >
311+ < div className = "main-content" >
312+ < h1 >
313+ React Client-Side { IDENTITY_NAME } SDK Integration Example with Google Secure Signals
314+ </ h1 >
315+ < p >
316+ 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{ ' ' }
317+ < a href = { `${ DOCS_BASE_URL } /guides/integration-javascript-client-side` } >
318+ Client-Side Integration Guide for JavaScript
319+ </ a > { ' ' }
320+ and{ ' ' }
321+ < a href = { `${ DOCS_BASE_URL } /guides/integration-google-ss` } >
322+ Google Ad Manager Secure Signals Integration Guide
323+ </ a > .
324+ </ p >
325+
326+ < div id = 'page-content' >
327+ < div id = 'video-container' >
328+ < video id = 'video-element' ref = { videoElementRef } onClick = { handlePlay } >
329+ < source src = 'https://storage.googleapis.com/interactive-media-ads/media/android.mp4' />
330+ < source src = 'https://storage.googleapis.com/interactive-media-ads/media/android.webm' />
331+ </ video >
332+ < div id = 'ad-container' ref = { adContainerRef } onClick = { handleAdContainerClick } > </ div >
333+ </ div >
334+ < button id = 'play-button' onClick = { handlePlay } >
335+ Play
336+ </ button >
330337 </ div >
331- < button id = 'play-button' onClick = { handlePlay } >
332- Play
333- </ button >
334- </ div >
335338
336- < div className = 'product-tables' >
337- < table id = 'uid2_state' >
338- < thead >
339- < tr >
340- < th > { IDENTITY_NAME } Status</ th >
341- </ tr >
342- </ thead >
339+ < h2 > { IDENTITY_NAME } Integration Status</ h2 >
340+ < table id = 'uid_state' >
343341 < tbody >
344342 < tr >
345- < td className = 'label' > Ready for Targeted Advertising:</ td >
343+ < td className = 'label' >
344+ < div className = "tooltip-wrapper" >
345+ Ready for Targeted Advertising:
346+ < div className = "tooltip" >
347+ < span className = "tooltip-trigger" > ?</ span >
348+ < div className = "tooltip-content" >
349+ Indicates whether a valid { IDENTITY_NAME } token is present and can be passed to Google Secure Signals for targeted advertising.
350+ </ div >
351+ </ div >
352+ </ div >
353+ </ td >
346354 < td className = 'value' >
347355 < pre > { targetedAdvertisingReady ? 'yes' : 'no' } </ pre >
348356 </ td >
349357 </ tr >
350358 < tr >
351- < td className = 'label' > { IDENTITY_NAME } Advertising Token:</ td >
359+ < td className = 'label' >
360+ < div className = "tooltip-wrapper" >
361+ Advertising Token:
362+ < div className = "tooltip" >
363+ < span className = "tooltip-trigger" > ?</ span >
364+ < div className = "tooltip-content" >
365+ The encrypted { IDENTITY_NAME } token passed to Google Secure Signals for advertising. It is automatically refreshed by the SDK in the background when expired.
366+ </ div >
367+ </ div >
368+ </ div >
369+ </ td >
352370 < td className = 'value' >
353371 < pre > { advertisingToken } </ pre >
354372 </ td >
355373 </ tr >
356374 < tr >
357- < td className = 'label' > Is { IDENTITY_NAME } Login Required?</ td >
375+ < td className = 'label' >
376+ < div className = "tooltip-wrapper" >
377+ Is Login Required?
378+ < div className = "tooltip" >
379+ < span className = "tooltip-trigger" > ?</ span >
380+ < div className = "tooltip-content" >
381+ Indicates whether a new { IDENTITY_NAME } token needs to be generated. Returns "yes" when no valid identity exists or the current identity has expired.
382+ </ div >
383+ </ div >
384+ </ div >
385+ </ td >
358386 < td className = 'value' >
359387 < pre > { loginRequired ? 'yes' : 'no' } </ pre >
360388 </ td >
361389 </ tr >
362390 < tr >
363- < td className = 'label' > { IDENTITY_NAME } Identity Callback State:</ td >
391+ < td className = 'label' >
392+ < div className = "tooltip-wrapper" >
393+ Has opted out?
394+ < div className = "tooltip" >
395+ < span className = "tooltip-trigger" > ?</ span >
396+ < div className = "tooltip-content" >
397+ Shows whether the user has exercised opt-out, in which case no advertising token may be generated or used.
398+ </ div >
399+ </ div >
400+ </ div >
401+ </ td >
402+ < td className = 'value' >
403+ < pre > { isOptedOut ? 'yes' : 'no' } </ pre >
404+ </ td >
405+ </ tr >
406+ < tr >
407+ < td className = 'label' >
408+ < div className = "tooltip-wrapper" >
409+ Identity Callback State:
410+ < div className = "tooltip" >
411+ < span className = "tooltip-trigger" > ?</ span >
412+ < div className = "tooltip-content" >
413+ The complete identity object returned by the SDK. Contains the full { IDENTITY_NAME } identity data including refresh tokens and metadata.
414+ </ div >
415+ </ div >
416+ </ div >
417+ </ td >
364418 < td className = 'value' >
365419 < pre > { identityState } </ pre >
366420 </ td >
367421 </ tr >
368422 < tr >
369- < td className = 'label' > Secure Signals Loaded?</ td >
423+ < td className = 'label' >
424+ < div className = "tooltip-wrapper" >
425+ Secure Signals Loaded?
426+ < div className = "tooltip" >
427+ < span className = "tooltip-trigger" > ?</ span >
428+ < div className = "tooltip-content" >
429+ Indicates whether Google Secure Signals has successfully loaded and cached the { IDENTITY_NAME } token.
430+ </ div >
431+ </ div >
432+ </ div >
433+ </ td >
370434 < td className = 'value' >
371435 < pre > { secureSignalsLoaded ? 'yes' : 'no' } </ pre >
372436 </ td >
373437 </ tr >
374438 < tr >
375- < td className = 'label' > Secure Signals Value:</ td >
439+ < td className = 'label' >
440+ < div className = "tooltip-wrapper" >
441+ Secure Signals Value:
442+ < div className = "tooltip" >
443+ < span className = "tooltip-trigger" > ?</ span >
444+ < div className = "tooltip-content" >
445+ The { IDENTITY_NAME } data stored by Google Secure Signals in local storage for use in ad requests.
446+ </ div >
447+ </ div >
448+ </ div >
449+ </ td >
376450 < td className = 'value' >
377451 < pre > { secureSignalsValue } </ pre >
378452 </ td >
379453 </ tr >
380454 </ tbody >
381455 </ table >
382- </ div >
383456
384- { isOptedOut ? (
385- < >
386- < div id = 'optout_banner' style = { { border : '3px solid #ffc107' , padding : '15px' , margin : '20px 0' } } >
387- < p style = { { margin : 0 } } > The email address you entered has opted out of { IDENTITY_NAME } .</ p >
457+ { isOptedOut ? (
458+ < >
459+ < div id = 'optout_banner' style = { { border : '3px solid #ffc107' , padding : '15px' , margin : '20px 0' } } >
460+ < p style = { { margin : 0 } } > The email address you entered has opted out of { IDENTITY_NAME } .</ p >
461+ </ div >
462+ < div id = 'optout_message' className = 'form' >
463+ < button type = 'button' className = 'button' onClick = { handleTryAnother } >
464+ Try Another Email
465+ </ button >
466+ </ div >
467+ </ >
468+ ) : ! isLoggedIn ? (
469+ < div id = 'login_form' className = 'form' >
470+ < div className = 'email_prompt' >
471+ < input
472+ type = 'text'
473+ id = 'email'
474+ name = 'email'
475+ placeholder = 'Enter an email address'
476+ value = { email }
477+ onChange = { handleEmailChange }
478+ />
479+ < button type = 'button' className = 'button' onClick = { handleLogin } >
480+ Generate { IDENTITY_NAME }
481+ </ button >
482+ </ div >
388483 </ div >
389- < div id = 'optout_message' className = 'form' >
390- < button type = 'button' className = 'button' onClick = { handleTryAnother } >
391- Try Another Email
392- </ button >
393- </ div >
394- </ >
395- ) : ! isLoggedIn ? (
396- < div id = 'login_form' className = 'form' >
397- < div className = 'email_prompt' >
398- < input
399- type = 'text'
400- id = 'email'
401- name = 'email'
402- placeholder = 'Enter an email address'
403- style = { { borderStyle : 'none' } }
404- value = { email }
405- onChange = { handleEmailChange }
406- />
407- </ div >
408- < div >
409- < button type = 'button' className = 'button' onClick = { handleLogin } >
410- Generate { IDENTITY_NAME }
484+ ) : (
485+ < div id = 'logout_form' className = 'form' >
486+ < button type = 'button' className = 'button' onClick = { handleLogout } >
487+ Clear { IDENTITY_NAME }
411488 </ button >
412489 </ div >
490+ ) }
491+ </ div >
492+
493+ < aside className = "sidebar" >
494+ < h3 > 📋 How to Test</ h3 >
495+
496+ < div className = "section" >
497+ < h4 > Step 1: Generate { IDENTITY_NAME } </ h4 >
498+ < ul >
499+ < li > Enter an email address in the input field</ li >
500+ < li > Click "Generate { IDENTITY_NAME } " button</ li >
501+ < li > The SDK will initialize and request a token</ li >
502+ </ ul >
413503 </ div >
414- ) : (
415- < div id = 'logout_form' className = 'form' >
416- < form >
417- < button type = 'button' className = 'button' onClick = { handleLogout } >
418- Clear { IDENTITY_NAME }
419- </ button >
420- </ form >
504+
505+ < div className = "section" >
506+ < h4 > Step 2: View Video Ad</ h4 >
507+ < ul >
508+ < li > Click the "Play" button to start the video</ li >
509+ < li > Google Secure Signals will use the { IDENTITY_NAME } token</ li >
510+ < li > Observe ad targeting with { IDENTITY_NAME } </ li >
511+ </ ul >
512+ </ div >
513+
514+ < div className = "section" >
515+ < h4 > Step 3: Verify Secure Signals</ h4 >
516+ < ul >
517+ < li > Check "Secure Signals Loaded?" changes to "yes"</ li >
518+ < li > View the Secure Signals value in the table</ li >
519+ < li > Token is stored in localStorage for ad requests</ li >
520+ </ ul >
521+ </ div >
522+
523+ < div className = "section" >
524+ < h4 > Step 4: Test Opt-Out</ h4 >
525+ < ul >
526+ < li > Clear
{ IDENTITY_NAME } , then try:
< strong > [email protected] </ strong > </ li > 527+ < li > Observe "Has opted out?" changes to "yes"</ li >
528+ < li > No advertising token or Secure Signals are generated</ li >
529+ </ ul >
530+ </ div >
531+
532+ < div className = "section" >
533+ < h4 > What's Happening?</ h4 >
534+ < ul >
535+ < li > < strong > Client-Side Token Generation:</ strong > The SDK generates tokens directly in the browser using your public credentials</ li >
536+ < li > < strong > Secure Signals Integration:</ strong > Google Secure Signals automatically retrieves and caches the { IDENTITY_NAME } token</ li >
537+ < li > < strong > Local Storage:</ strong > Both SDK identity and Secure Signals data are stored in localStorage for persistence</ li >
538+ </ ul >
539+ </ div >
540+
541+ < div className = "note" >
542+ < strong > Note:</ strong > This is a test-only environment. Do not use real user data.
421543 </ div >
422- ) }
544+ </ aside >
423545 </ div >
424546 ) ;
425547} ;
0 commit comments