Select a URL with Shared Storage

Select a URL based on data collected in Shared Storage, and render the content in a fenced frame.

With the Shared Storage API, you can select a URL to be rendered into a fenced frame using cross-site data. Use JavaScript to read and write cross-site data, then select a URL from a provided list based on your stored data. You can render that URL in a fenced frame.

URL selection can include any kind of content: ads, articles, images, HTML, calls-to-action (such as buttons), and more.

For example, let's say you run a travel site and are running an ad campaign with three different ad creatives. You want to sequence these creatives based on the user's interactions (view or click).

Three ad creatives, which are shown to users based on their previous interaction.
The first creative for a new viewer says, "Go on your next adventure." With just a view and no click, the user would see, "Explore weekend getaways." After viewing or clicking, the third creative encourages users to "Click to get your Hotel Discount." If the user clicks on the first ad, the next ad they would see is the third creative.

When a user first observes a winning ad space, you can store an ID and click status for that creative in Shared Storage. This means when you win an ad auction on other sites that this user visits, you can display a different ad based on that data.

Shared Storage walk-through with three ad creatives and user interaction.

Your JavaScript runs in a worklet to retrieve this information, but your code cannot interact with or communicate outside of the iframe or fenced frame on the parent page.

Let's take another example. Let's say you're interested in testing which article would perform better in an embedded context. You can assign a user to an experiment group when you see that user on your site, then store that group ID in Shared Storage to be accessed in a cross-site context. On another site, your fenced frame can select a URL based on that user's experiment group as stored with Shared Storage.

Shared Storage allows you to make informed decisions based on cross-site data, without sharing user information (such as browser history or other personal details) with an embedding site or exfiltrating data to your own servers.

Use cases

URL selection with Shared Storage supports use cases such as the following:

  • Rotate ad creatives: You can store data, such as creative ID and user interaction, to determine which creative users' see across different sites.
    • Frequency. Browser view counts can be stored in Shared Storage and used to decide which creative is shown to a user.
  • Run A/B testing: Assign a user to an experiment group, then store that group ID with Shared Storage to be accessed cross-site.
  • Customize user experience: Share custom content and calls-to-action based on a user's registration status or other user verification states.

Budgets

To mitigate the risk of cross-site data leakage, the Select URL API uses a budgeting system with a combination of long-term and short-term budgets:

  • Long-term budget: 12 bits per-caller-site per-day budget when using selectURL(). This budget is only charged if the frame hosting the selected URL performs a top-level navigation, where the cost is calculated as log2(number of URLs). So, if you provide 8 URLs to choose from, the cost is 3 bits. Any remaining budget for the day is calculated as 12 - (sum of bits deducted in the last 24 hours) and if there is insufficient budget left, the default URL (the first URL in the list) is returned and 1 bit is logged if the default URL is navigated to.
  • Short-term budgets: additional limits on a per-page-load basis. There is a 6 bits per-calling-site per-page load budget limiting how much a single calling-site can leak using selectURL(). There is also a 12 bits overall per-page load budget which is a combined limit for all calling-sites on a page.

    Saved queries let you reuse a previous selectURL() result on the same page, reducing short-term budget usage. When selectURL() is called with a saved query name for the first time, the resulting index will be stored for the lifetime of the page. When selectURL() is called with the same saved query name for follow-up calls, the stored index will be returned and the registered operation won't run. In this case the budget will only be charged on the first use, but not on any reuses within the same page load since no net-new information is revealed.

    Saved queries can be implemented by adding the savedQuery property, with your chosen query name, to the options object as shown in the following example.

    const topProductUrls = [
      { url: 'https://ad.example/default-top-product.html' },
      { url: 'https://ad.example/experiment-top-product.html' }];
    const relatedProductUrls = [
      { url: 'https://ad.example/default-related-product.html' },
      { url: 'https://ad.example/experiment-related-product.html' }];
    
    // This is the first call to `selectURL()` with `savedQuery: 'control_or_experiment'`
    // on this page, so it will be charged to both per-page budgets.
    const topProductsConfig = await sharedStorage.selectURL(
      'productExperiment', topProductUrls, {
        savedQuery: 'control_or_experiment',
        keepAlive: true,
        resolveToConfig: true
    });
    document.getElementById('topProductsFencedFrame').config = topProductsConfig;
    
    // This next call with this savedQuery won't charge either of the per-page budgets.
    const relatedProductConfig = await sharedStorage.selectURL(
      'productExperiment', relatedProductUrls, {
        savedQuery: 'control_or_experiment',
        resolveToConfig: true
    });
    document.getElementById("relatedProductFencedFrame").config = relatedProductConfig;
    

Try URL selection

URL selection with the Shared Storage API is available for testing in Chrome Canary/Dev/Beta M105+. To test URL selection, enable all the Ad privacy APIs under chrome://settings/adPrivacy.

Experiment with the demo

A demo is available, and you can review the code on GitHub.

This demo is constructed from the perspective of an advertiser, ad tech, content distributor or other third-party service that wants to store information across different publishers' sites. In the demo, the same third-party code runs on both Publisher A and Publisher B sites for each use case. Visit each publisher's page to see how the data is shared in a cross-site context.

Engage and share feedback

The Shared Storage proposal is under active discussion and subject to change in the future. If you try this API and have feedback, we'd love to hear it.