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
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.
- GitHub: Read the proposal, reach whitepaper, raise questions and participate in discussion.
- Shared Storage API announcements: Join or view past announcements on our mailing list
- Developer support: Ask questions and join discussions on the Privacy Sandbox Developer Support repo.