privacysandbox/privacy-sandbox-demos

Topics fetch API always showing ();p=P0000000000000000000000000000000 as sec-browsing-topics header

Closed this issue · 6 comments

After following the demo instructions on https://topics-fetch-demo.glitch.me/, the fetch calls on the 4 topics sites are always showing ();p=P0000000000000000000000000000000 as the Sec-Browsing-Topics header value.

Screenshot 2024-02-15 at 1 58 36 PM



I've followed the demo's setup and troubleshooting:

  • Chrome launched via command lined w/ the specified feature flags
  • Enabled chrome://flags/#privacy-sandbox-enrollment-overrides and added all the listed glitch.me subdomains
  • chrome://flags/#privacy-sandbox-ads-apis is disabled
  • No adblocker or incognito mode
  • "Allow all cookies" enabled

Hi @doctafaustus -- thanks for reporting this.

Do you get any errors logged to the DevTools console, for any of the pages?

Could you post a screenshot of chrome://topics-internals?

For the chrome://flags/#privacy-sandbox-enrollment-overrides URLs, ensure that all the following are added

(Apologies — https://topics-server.glitch.me somehow got removed from the instructions.)

https://topics-server.glitch.me,https://topics-demo.glitch.me,https://pets-animals-pets-cats.glitch.me,https://cats-cats-cats-cats.glitch.me,https://cats-pets-animals-pets.glitch.me,https://topics-fetch-demo.glitch.me,https://tennis-tennis.glitch.me,https://tennis-tennis-tennis.glitch.me,https://baseball-baseball.glitch.me,https://cricket-cricket.glitch.me

Thanks @samdutton, adding https://topics-server.glitch.me to the chrome://flags/#privacy-sandbox-enrollment-overrides URLs and clicking the "Calculate Now" button on chrome://topics-internals/ got it working. Much appreciated.

@samdutton, just a follow-up question after learning from the nice demos you have...

I’m curious to know how this may work with sites that wish to use an advertising partner. With this fetch method, it seems like it’s designed only for the original site to add this code to observe and access the user topics and then send those topics to their partner’s ad server on their own, and not via the 3rd party script hosted by their ad partner’s domain.
In other words, an ad partner’s client script is not supposed to use Topics API but rather the original site so it can send the topics data to their partners - is that correct?
I believe this is case based on the fetch call needing to target the same domain as the call.

If the site already included an ad partner’s JS snippet hosted on another domain, could that script observe and access topics via the iframe (document.browsingTopics()) method via iframe injection? Something like this:

// ad-partner-script.js on another-domain.com
function addIframeWithScript() {
  const iframe = document.createElement('iframe');

  iframe.onload = function() {
    const script = document.createElement('script');
    script.innerHTML = `
      console.log("Script executed inside iframe");
      async function getTopics() {
        const topics = await document.browsingTopics();
        console.log('topics:', topics);
      }
      getTopics();
    `;
    iframe.contentDocument.body.appendChild(script);
  };

  document.body.insertAdjacentElement('beforeend', iframe);
}

addIframeWithScript();

My initial testing showed that this would return an empty array for topics and I’m wondering if that’s by design, where it would only work if the Topics API code was hosted on the same domain and the original site and that’s the intention behind this design. Thank you!

Hi @doctafaustus

The Topics JavaScript API and headers are both primarily designed for third-party providers.

For example, an ad tech might provide an iframe that accesses the Topics API. This iframe can be embedded on the ad tech's partner sites using JavaScript (like your example) or as an HTML element. Page visits (i.e. for the top-level page) can be recorded by Topics (where allowed by user and site settings) on sites where the iframe is embedded.

The ad tech can then access topics for the user either by calling the Topics JavaScript API (like your example), or by accessing headers from a fetch() request with a {browsingTopics: true} option, or by accessing headers for an iframe with a browsingtopics attribute. The caller in this case is the domain of the iframe src (for the JavaScript API or iframe header), or the domain of the fetch() request URL.

A caller will only receive topics that they have observed for a user. This means the caller (e.g. an ad tech) needs to have a presence on multiple sites the user visits (like topics-fetch-demo.glitch.me).

I think your code is fine -- it's just that the caller another-domain.com isn't observing topics for the user (i.e. you).

Hope that makes sense!

Sam

Thanks @samdutton, I understand now - that the iframe script does need to be hosted on the ad tech's platform domain so that this domain can have the presence on multiple sites b/c it can only access topics it has observed.
So it seems like the iframe script injection is fine but the src attribute has to be set with this domain. Thanks!