Eigentlich sollte es nur ein einziger Link sein
Das Vorhaben war ziemlich klein.
Für die Prüfung bei einem Affiliate-Dienst sollte in einem Artikel auf der Website ein einziger Produktlink zu einer externen Festplatte stehen. Vor dem Link steht deutlich der Hinweis: „Diese Seite enthält Affiliate-Links. Beim Kauf erhält der Betreiber unter Umständen eine Provision.“ Produktlink erstellen, in den Artikel einfügen, auf GitHub committen.
Das war erledigt.
Doch in dem Moment, in dem der Code auf GitHub lag, kam ein Irrtum ans Licht.
Auf GitHub zu liegen und im Internet veröffentlicht zu sein, sind zwei verschiedene Dinge.
GitHub Actions, die ich normalerweise nutze, standen nicht zur Verfügung. Dann kam die Idee auf, genau diese eine Seite über einen Cloudflare Worker abzufangen und auszuliefern. Auch dieser Weg ist unter den diesmal geltenden Nutzungsbedingungen nicht möglich.
Dabei wollte ich nur einen Link platzieren, und plötzlich saß ich in einer Deployment-Konferenz: „Was ist mit CI? Mit dem Worker? Pages per Git-Anbindung oder Direct Upload?“
Es war der Baubeginn von „Affiliate-Sagrada-Família, Gebäude 2“.
Wenn man die Mechanismen aber auseinanderhält, wird die Sache plötzlich ganz einfach.
1. Warum brauchte es überhaupt eine öffentliche Seite?
Im Onboarding von Sovrn Commerce für Content und Blogs ist beschrieben: Man baut die Commerce-Links auf der angemeldeten Website ein, erzeugt Klicks und geht erst dann in die Prüfung. [3]
Es heißt also nicht „Wenn die Prüfung bestanden ist, setze ich den Link“, sondern: Man muss zuerst einen Zustand herstellen, in dem die prüfende Seite ein Umsetzungsbeispiel sehen kann.
Außerdem empfiehlt Sovrn, auf jeder Seite mit Affiliate-Links für die Lesenden gut verständlich offenzulegen, dass eine Vergütungsbeziehung besteht. Auch der Gedanke, den Hinweis an einer Stelle zu platzieren, die vor dem Link und der Werbung sichtbar ist, wird genannt. [4]
Gebraucht wird hier keine aufwendige Produktvergleichsseite.
Die Anforderungen sind ziemlich schlicht:
- Es gibt einen Artikel auf der echten Website
- In diesem Artikel steht der Affiliate-Link
- Vor dem Link steht der Offenlegungshinweis
- Die Seite lässt sich über die öffentliche URL ganz normal aufrufen
- Nach der Umsetzung lassen sich einige Bestätigungsklicks auslösen
Wichtig ist der vorletzte Punkt.
„Das HTML liegt auf GitHub“ ist nicht dasselbe wie „Die Seite ist unter der öffentlichen URL sichtbar“.
2. Wenn GitHub Actions ausfällt, steht Cloudflare Pages nicht zwingend still
GitHub Actions ist ein CI/CD-System (also ein System, das automatisch baut, testet und ausliefert), das Builds, Tests und Deployments auf GitHub ausführt.
Cloudflare Pages dagegen hat eine Git-Integration, die GitHub oder GitLab direkt anbindet. Wird eine Änderung in das verbundene Repository gepusht, führt Cloudflare selbst Build und Deployment aus. [1]
Der Ablauf sieht also so aus:
Push zu GitHub → Cloudflare Pages erkennt die Änderung → Cloudflare baut → Cloudflare deployt
Auf diesem Weg braucht man keinen GitHub-Actions-Workflow.
Das ist ziemlich wichtig.
Dass „GitHub Actions nicht nutzbar“ ist, heißt nicht gleich, dass „GitHub nicht automatisch nach Cloudflare veröffentlichen kann“. Actions und die Git-Anbindung von Cloudflare Pages sind zwei getrennte Dinge.
Ein Vergleich aus der Fabrik: GitHub Actions ist der interne Transportroboter. Die Git-Integration von Cloudflare ist ein Vertrag, bei dem ein externes Lager die Ware selbst abholt.
Auch wenn der Transportroboter steht, steht der Abholdienst nicht unbedingt still.
3. Zuerst prüfen: „Welcher Art ist dieses Pages-Projekt?“
Bei Cloudflare Pages wird es schnell zum Labyrinth, wenn man das offenlässt.
Grob gibt es zwei Veröffentlichungswege.
| Methode | Was ist der Auslöser? | Build/Deployment | Wofür geeignet |
|---|---|---|---|
| Git-Integration | Push zu GitHub / GitLab | Auf Cloudflare-Seite | Das Repository ist die Quelle der Wahrheit und soll automatisch veröffentlicht werden |
| Direct Upload | Vorab erzeugte Build-Artefakte | Wrangler oder Dashboard | Lokal oder in einer eigenen CI gebaute Artefakte sollen direkt hochgeladen werden |
Laut der offiziellen Cloudflare-Dokumentation lässt sich ein per Git-Integration angelegtes Pages-Projekt später nicht in ein normales Direct-Upload-Projekt umwandeln. Dagegen kann man in ein Git-verbundenes Projekt manuell mit Wrangler deployen, während Drag-and-drop im Dashboard bei einem bestehenden Git-Projekt nicht funktioniert. [1][2]
Umgekehrt kann man zu einem als Direct Upload gestarteten Projekt nachträglich keine Git-Integration hinzufügen, ohne das Projekt zu wechseln. Wer auf automatische Git-Anbindung umsteigen will, braucht ein neues Pages-Projekt. [2]
Die erste Frage lautet deshalb nicht: „Wie deploye ich?“
Sondern: „Ist das bestehende Pages-Projekt vom Typ Git-Integration oder Direct Upload?“
Sobald das klar ist, fällt die Hälfte der Optionen weg.
4. Beim Typ Git-Integration muss GitHub Actions nicht wiederbelebt werden
Wenn das GitHub-Repository und Cloudflare Pages bereits korrekt verbunden sind, ist der kürzeste Weg weder ein Worker noch eine neue CI.
Auf der Cloudflare-Pages-Seite prüft man Folgendes:
- Das Projekt ist mit dem richtigen GitHub-Repository verbunden
- Der Production-Branch ist der Branch, der wirklich veröffentlicht werden soll
- Der automatische Build des Production-Branches ist nicht deaktiviert
- Build-Befehl und Ausgabeverzeichnis passen zum aktuellen Projekt
- Nach dem Push wurde in der Deployments-Ansicht von Cloudflare Pages ein neues Deployment erzeugt
- Auf
pages.devwird der neue Text angezeigt - Zum Schluss wird derselbe Text auch unter der Custom Domain geprüft
Die Git-Integration von Cloudflare baut und deployt auf Grundlage von Commits im verbundenen Branch. [1]
Auch wenn GitHub Actions vorübergehend nicht nutzbar ist, bleibt die Veröffentlichungslinie bestehen, solange der native Cloudflare-Build läuft.
Es geht also nicht darum, „einen weiteren komplizierten Mechanismus anzubauen“, sondern darum, zu prüfen, ob die ohnehin vorhandene Cloudflare-Abholstelle geöffnet ist.
5. Beim Typ Direct Upload wirft man nicht „eine Seite“ hoch, sondern die Build-Artefakte
Direct Upload bedeutet, dass man einen fertigen Satz statischer Dateien an Cloudflare Pages übergibt. Laut offizieller Dokumentation lädt man vorab gebaute Assets über Wrangler oder das Dashboard hoch. [2]
Hier lauert eine gefährliche Idee.
„Reicht es nicht, nur das neu hinzugekommene HTML zu Cloudflare zu schicken?“
Bei einer Konfiguration, die die gesamte statische Website baut, sollte man das grundsätzlich vermeiden.
Denn die Einheit beim Deployment ist nicht „eine Datei aus dem Git-Diff“, sondern die Build-Ausgabe, die die Website zu diesem Zeitpunkt ausmacht.
Wenn Seitenübersicht, CSS, JavaScript, Suchindex, Assets und Routing zusammen erzeugt werden, trennen sich Produktion und Repository voneinander, sobald man eine einzelne Seite von Hand einschiebt.
Wer Direct Upload nutzt, folgt im Prinzip diesem Ablauf:
Neuesten Stand holen → Build-Befehl des Projekts ausführen → Ausgabeverzeichnis prüfen → gesamte Ausgabe deployen → Produktions-URL prüfen
Bei einer statischen Node-Website führt man zum Beispiel den projektspezifischen Build-Befehl wie pnpm build aus und lädt das erzeugte Verzeichnis, etwa dist, hoch.
Wichtig ist, die Produktion nicht zu einer „seltsamen Parallelwelt zu machen, in der eine einzige Datei von Hand geändert wurde“.
6. Wenn der Worker als Ausweg nicht zur Verfügung steht, streicht man ihn einfach
Wenn man eine einzelne Seite dringend veröffentlichen will, ist die Idee, nur einen bestimmten Pfad per Worker-Route abzufangen, an sich tragfähig.
Wenn aber wie hier auch der Worker-Weg nach den Nutzungsbedingungen nicht zur Verfügung steht, ergibt es keinen Sinn, ihn zum Kern des Plans zu machen.
Je mehr Wege im Plan stehen bleiben, die man gar nicht nutzen kann, nur weil es vielleicht doch geht, desto komplizierter wird der Betrieb.
- GitHub Actions ist nicht nutzbar
- Worker ist auch nicht nutzbar
- Dann bleiben nur Git-Integration oder Direct Upload von Cloudflare Pages
Das reicht.
Statt zehn Notausgänge zu bauen, geht es schneller, den einen Haupteingang zu finden, der gerade offen ist.
Wegen eines einzigen Affiliate-Links baut man nicht noch ein zweites Deployment-Gebäude.
Das war die größte Lehre aus dieser Sache.
7. „Veröffentlicht“ misst man an der echten Seite, nicht am Commit-SHA
Gefährlich im Webbetrieb ist es, einen Zwischenschritt für das Ergebnis zu halten.
- Code geschrieben
- Auf GitHub committet
- Build erfolgreich
- Deployment bei Cloudflare erstellt
Alles wichtig, aber Lesende sehen nur die endgültige URL.
Bei einer Affiliate-Prüfseite wie dieser wird zum Schluss Folgendes kontrolliert:
- Die öffentliche URL lässt sich zum Beispiel in einem Inkognito-Fenster öffnen
- Der aktuelle Artikeltext wird angezeigt
- Der Affiliate-Hinweis ist vor dem Link sichtbar
- Der Produktlink führt zum erwarteten Ziel
- Auch auf dem Smartphone ist die Darstellung nicht kaputt
- Bei Bedarf werden einige Bestätigungsklicks ausgelöst
- Bei Sovrn werden Klickmessung und Prüfstatus kontrolliert
Sovrn beschreibt für Content-/Blog-Kampagnen den Ablauf, dass erst geprüft wird, nachdem die Links eingebaut sind und Klicks ausgelöst wurden. [3]
„Es ist auf GitHub, also warte ich auf die Prüfung“ gilt deshalb nicht. Erst wenn man die Umsetzung unter der Produktions-URL zeigen kann, ist die Startlinie erreicht.
8. Danach sollte man Affiliate-URLs nicht in den Artikeltext einbrennen
Dieser eine Link kann von Hand gesetzt werden.
Wächst die Zahl der Artikel aber auf Hunderte oder Tausende, entsteht neben der Artikelfabrik eine Werbefabrik, wenn Menschen jedes Mal von Hand entscheiden: „Kommt in diesen Artikel Werbung? Wohin? Welches Produkt? Für welches Land?“
In der nächsten Stufe lassen sich Text und Monetarisierungsdaten besser trennen.
Auf Artikelseite hält man zum Beispiel nur ein kleines Monetization-Manifest:
article_id: example-123
affiliate: true
placement: after_solution
max_products: 3
market_mode: auto
product_theme: external-storage
Und beim Veröffentlichen läuft es so:
Artikel → Monetarisierungs-Gate → Produktkandidaten → Affiliate-Link erzeugen → Renderer fügt ein → Erfolgsmessung
Der Text bleibt ein langfristiges Gut, während Produkt-URLs, Lagerbestand, Händler und länderspezifisches Routing austauschbare Bauteile sind.
So muss man bei toten Links oder Produktänderungen nicht jedes Mal den Text in 12 Sprachen durchwühlen.
Affiliate ist nicht der Artikel selbst.
Es ist besser, ihn als Vertriebsleitung zu verstehen, die sich nachträglich an den Artikel anschließen lässt. Das ist im Langzeitbetrieb stärker.
9. Fazit: Wenn die CI ausfällt, erst den Eingang von Cloudflare prüfen, bevor man eine neue Burg baut
Der Ablauf war ziemlich bezeichnend.
Es begann mit: „Für die Prüfung setze ich einen einzigen Produktlink zu einer Festplatte.“
Der Link war erstellt. Der Offenlegungshinweis war geschrieben. Auf GitHub war auch alles.
Aber beim Schritt in die Produktion ging GitHub Actions nicht. Auch der Versuch, über einen Worker auszuweichen, scheiterte, weil dieser Weg nicht verfügbar war.
Wenn man jetzt noch einen neuen Mechanismus hinzufügt, verschiebt sich das Ziel von „den Link veröffentlichen“ zu „ein Deployment-System ausbauen“.
Zusammengefasst braucht es nur diese Entscheidungen:
- Ist das bestehende Pages-Projekt vom Typ Git-Integration, nutzt man den nativen Cloudflare-Build
- Bei Direct Upload baut man die gesamte Website und deployt das reguläre Artefakt
- Ist der Worker nicht nutzbar, streicht man ihn aus den Kandidaten
- Einen GitHub-Commit nennt man nicht „veröffentlicht“
- Unter der endgültigen URL prüft man Offenlegungshinweis, Link, Darstellung und Klicks
Technisch am gefährlichsten ist nicht, dass es wenige Optionen gibt.
Gefährlich ist es, wenn Optionen im Plan stehen bleiben, die man gar nicht nutzen kann.
Die Antwort auf das Deployment-Labyrinth, das mit einem einzigen Link begann, war überraschend unspektakulär.
Zuerst nachsehen, welcher Art das eigene Cloudflare-Pages-Projekt ist.
Das reichte schon.

