Many content producers and advertisers want to know how many unique people saw their content. Use Shared Storage to record the first time a user saw your ad, embedded video, or publication, and prevent duplicative counting of that same user on different sites. You can then use the Private Aggregation API to output a summary report for your reach.
The Shared Storage API is a Privacy Sandbox proposal for general purpose, cross-site storage, which supports many possible use cases. Private Aggregation API is an output available in Shared Storage that lets you to aggregate cross-site data. To learn more about methods to implement these measurements, check out our reach whitepaper.
Try unique reach measurement
To experiment with unique reach measurement with Shared Storage and Private Aggregation, confirm you're using Chrome M107 or later. Enable all the Ad privacy APIs under chrome://settings/adPrivacy
.
You can also enable Shared Storage with the --enable-features=PrivacySandboxAdsAPIsOverride,OverridePrivacySandboxSettingsLocalTesting,SharedStorageAPI,FencedFrames
flag in the command line.
Experiment with code samples
You may want to keep track of how many unique users have seen your content across different sites. In this example, the content ID dimension is encoded into the aggregation key (bucket), and the count is used as the aggregatable value. The summary report will contain information such as "Approximately 391 users have seen the content ID 123."
In this example:
* unique-reach-measurement.js
is loaded via a frame, and is responsible for loading the shared storage worklet.
* unique-reach-measurement-worklet.js
is the shared storage worklet that checks the flag in shared storage and sends a report via the Private Aggregation API.
async function measureUniqueReach() {
// Load the Shared Storage worklet
await window.sharedStorage.worklet.addModule('reach-measurement-worklet.js');
// Run the reach measurement operation
await window.sharedStorage.run('reach-measurement', { data: { contentId: '1234' } });
}
measureUniqueReach();
// Learn more about noise and scaling from the Private Aggregation fundamentals
// documentation on Chrome blog
const SCALE_FACTOR = 65536;
function convertContentIdToBucket(contentId) {
return BigInt(contentId);
}
class ReachMeasurementOperation {
async run(data) {
const { contentId } = data;
// Read from Shared Storage
const key = 'has-reported-content';
const hasReportedContent = (await sharedStorage.get(key)) === 'true';
// Do not report if a report has been sent already
if (hasReportedContent) {
return;
}
// Generate the aggregation key and the aggregatable value
const bucket = convertContentIdToBucket(contentId);
const value = 1 * SCALE_FACTOR;
// Send an aggregatable report via the Private Aggregation API
privateAggregation.contributeToHistogram({ bucket, value });
// Set the report submission status flag
await sharedStorage.set(key, true);
}
}
// Register the operation
register('reach-measurement', ReachMeasurementOperation);
Engage and share feedback
Note that the Shared Storage API proposal is under active discussion and development and therefore subject to change.
We're eager to hear your thoughts on the Shared Storage API.
- Proposal: Review the detailed proposal.
- Discussion: Join the ongoing discussion to ask questions and share your insights.
Stay Informed
- Mailing List: Subscribe to our mailing list for the latest updates and announcements related to the Shared Storage API.
Need Help?
- Developer Support: Connect with other developers and get answers to your questions in the Privacy Sandbox Developer Support repository.