Signatur
Beschreibung
SharedStorageSelectURLOperation gehört zur Shared Storage API der Privacy Sandbox. Sie ist eines von zwei Ausgabe-Gates. Das andere ist die Run-Operation mit Private Aggregation. Über diese Gates dürfen Daten, die seitenübergreifend gespeichert wurden, das Worklet nur in stark begrenzter Form verlassen. Bei der URL-Auswahl verlässt nur der Index einer URL das Worklet. Rohdaten bleiben drin. Die gewählte URL wird dann undurchsichtig in einem <fencedframe> angezeigt (übergangsweise auch in einem <iframe>). Die einbettende Seite erfährt nicht, welche URL gewählt wurde.
Du rufst die Schnittstelle nicht direkt auf. Stattdessen schreibst du im Worklet-Modul eine eigene Klasse, die dem Interface entspricht. Sie braucht eine asynchrone Methode run(urls, data). Diese gibt als Ganzzahl den Index der gewählten URL zurück. Mit register(name, Klasse) meldest du die Klasse unter einem Namen an. Auf der Seite lädst du das Modul mit window.sharedStorage.worklet.addModule() und startest die Operation mit window.sharedStorage.selectURL(name, urls, options).
Typische Einsätze:
- A/B-Tests über Websites hinweg: Ein Nutzer bleibt überall in derselben Testgruppe.
- Werbemittel abwechseln (Creative Rotation) und begrenzen, wie oft eine Anzeige erscheint (Frequency Capping).
- Bekannten Kunden andere Inhalte zeigen, zum Beispiel ein anderes Banner für Nutzer, die schon gekauft haben.
Im Worklet kannst du mit sharedStorage.get(), keys(), entries() und length() lesen. Mit set(), append(), delete() und clear() kannst du auch schreiben. Netzwerkzugriffe und DOM-Zugriffe gibt es im Worklet nicht.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $urls Pflicht | string[] | Parameter von run(): die Liste der Kandidaten-URLs, die die Seite an selectURL() übergeben hat. Auf der Seite gibst du sie als Objekte { url, reportingMetadata } an. Im Worklet kommen nur die URL-Strings an. Erlaubt sind höchstens 8 Einträge. |
|
| $data | any | undefined | Parameter von run(): beliebige, strukturiert klonbare Daten aus options.data des selectURL()-Aufrufs, zum Beispiel eine Kampagnen-ID. |
| $name (register) Pflicht | string | Der Name, unter dem die Operation mit register(name, OperationClass) angemeldet wird. selectURL(name, …) verweist auf diesen Namen. |
|
| $options (selectURL) | { data?: any, resolveToConfig?: boolean, keepAlive?: boolean, privateAggregationConfig?: object } | {} | Optionen des Aufrufs auf der Seite. resolveToConfig: true liefert eine FencedFrameConfig statt einer urn:uuid-URN. Mit keepAlive: true bleibt das Worklet für weitere Operationen verfügbar. |
Beispiele
Worklet-Modul: A/B-Test über Websites hinweg
// ab-test-worklet.js – wird im Shared-Storage-Worklet ausgeführt
class SelectExperimentGroup {
async run(urls, data) {
// Gruppe lesen, die beim ersten Besuch festgelegt wurde
const group = await sharedStorage.get(data.experimentName);
const index = Number.parseInt(group ?? '0', 10);
// Index absichern, sonst gilt URL 0 als Standard
return index >= 0 && index < urls.length ? index : 0;
}
}
register('select-experiment-group', SelectExperimentGroup);
Seite: Gruppe festlegen, URL auswählen und im Fenced Frame anzeigen
// main.js – läuft im Kontext der Seite bzw. eines Drittanbieter-Skripts
const runExperiment = async () => {
if (!window.sharedStorage) {
console.log('Shared Storage nicht verfügbar');
return;
}
// Gruppe nur beim ersten Mal zufällig setzen
await window.sharedStorage.set('button-color', String(Math.floor(Math.random() * 2)), {
ignoreIfPresent: true,
});
await window.sharedStorage.worklet.addModule('/ab-test-worklet.js');
const config = await window.sharedStorage.selectURL(
'select-experiment-group',
[
{ url: 'https://cdn.example/button-blue.html', reportingMetadata: { click: 'https://report.example/blue' } },
{ url: 'https://cdn.example/button-green.html' },
],
{ data: { experimentName: 'button-color' }, resolveToConfig: true }
);
const frame = document.createElement('fencedframe');
frame.config = config; // Seite erfährt nicht, welche URL gewählt wurde
document.body.append(frame);
};
runExperiment();
Frequency Capping: Anzeige höchstens dreimal zeigen
// frequency-cap-worklet.js
class FrequencyCapOperation {
async run(urls, { campaignId, maxViews }) {
const key = `views:${campaignId}`;
const views = Number(await sharedStorage.get(key) ?? 0);
if (views >= maxViews) {
return 1; // Ersatz-Werbemittel
}
await sharedStorage.set(key, String(views + 1));
return 0; // eigentliche Kampagnen-Anzeige
}
}
register('frequency-cap', FrequencyCapOperation);
// Aufruf auf der Seite:
// const urn = await window.sharedStorage.selectURL('frequency-cap',
// [{ url: 'https://ads.example/kampagne.html' }, { url: 'https://ads.example/ersatz.html' }],
// { data: { campaignId: 'sommer24', maxViews: 3 } });
// document.querySelector('iframe').src = urn; // urn:uuid:…
// Wichtig · Fallstricke
Kompatibilität und Zukunft: Die API ist experimentell und nicht standardisiert. Sie läuft nur in Chromium-Browsern, und dort meist nur, wenn die Website für die Privacy Sandbox angemeldet ist (Enrollment und Attestation). Google hat 2025 angekündigt, mehrere Privacy-Sandbox-Techniken einzustellen. Für neue Produkte solltest du dich deshalb nicht darauf verlassen und immer einen Ersatzweg einbauen, zum Beispiel mit if ('sharedStorage' in window).
- Entropie-Budget: Jede Navigation zu einer ausgewählten URL verbraucht
log2(Anzahl URLs)Bit aus einem Budget. Das Budget gilt pro Website und 24 Stunden. Ist es aufgebraucht, wird immer die URL mit Index 0 gewählt. Setze deshalb die sinnvollste Standard-URL an die erste Stelle. - Es sind höchstens 8 URLs pro Aufruf erlaubt. Gibt
run()einen ungültigen Index zurück oder wirft einen Fehler, wird ebenfalls die URL mit Index 0 verwendet. - Das Ergebnis ist absichtlich opak: eine
urn:uuid-URL oder einFencedFrameConfig-Objekt. Die Seite erfährt nicht, welche URL gewählt wurde. - Im Worklet gibt es weder DOM noch
fetch()oder Netzwerkzugriffe.sharedStorage.get()ist nur innerhalb von Ausgabe-Gates wie dieser Operation erlaubt. - Mit der Option
keepAlive: truebleibt das Worklet nach dem Aufruf erhalten und kann weitere Operationen ausführen. Standardmäßig ist nach einer Operation Schluss.