Digitales Produkt Landingpage - Konfigurationsanleitung

Digitales Produkt Landingpage - Konfigurationsanleitung

Konfigurationsanleitung

Zielgruppe: Backend-Administratoren (Backend)

Dieses Dokument beschreibt die Backend-Konfiguration des Moduls Digitales Produkt – Landingpage. Es richtet sich an Mitarbeiter, die im Backend Module für einen Shop aktivieren und konfigurieren.

Voraussetzungen

  • Das Modul DigitalProductPage muss dem Mandanten in der Modulverwaltung zugewiesen sein.

Schritt 1: Konfigurationsseite öffnen

Im Backend unter Add-Ons → Digitales Produkt – Landingpage öffnet sich die Modul-Konfiguration. Ganz oben befindet sich die Shop-Auswahl: die Konfiguration ist pro Shop, jeder Shop kann unterschiedliche Einstellungen haben.

grafik-20260422-131445.png

 

Schritt 2: URL-Aufbau verstehen

Direkt nach dem Öffnen der Seite zeigt eine blaue Info-Box, wie eine fertige Landingpage-URL aussieht:

https://<shop-domain>/page/{prefix}/{name}
  • {prefix} ist die öffentliche Benutzer-ID (siehe Schritt 4).

  • {name} ist der Name der Landingpage, wird vom Shop-Benutzer selbst gewählt.

Im unteren Bereich der Box wird ein Live-Beispiel mit den aktuell ausgewählten Einstellungen gerendert. Sobald in den Feldern unten etwas geändert wird, aktualisiert sich das Beispiel sofort – so kann vor dem Speichern geprüft werden, was die Einstellungen konkret bewirken.

Schritt 3: Modul für Shop aktivieren

Feld

Beschreibung

Feld

Beschreibung

Modul für Shop aktivieren

Schaltet das Modul für den ausgewählten Shop ein. Erst danach erscheint im Shop der Verwaltungs-Menüpunkt für Shop-Benutzer und die öffentlichen Landingpage-URLs werden erreichbar.

Maximale Anzahl Landingpages pro Benutzer

Standard ist 1. Solange der Wert auf 1 steht, wird dem Shop-Benutzer im Frontend keine Mehrfach-Verwaltung angezeigt – er sieht nur seine eine Landingpage. Ab 2 erscheinen Anlegen-/Löschen-Schaltflächen. Hartes Limit: 10. Höhere Werte werden vom Server automatisch auf 10 reduziert, auch wenn das HTML-Limit umgangen wird.

Schritt 4: Prefix-Strategie wählen

Die wichtigste Entscheidung. Sie bestimmt, wie der {prefix} in der URL gebildet wird.

Option A: Automatisch generierte, nicht erratbare ID (Empfehlung)

Das System erzeugt für jeden Shop-Benutzer einmalig eine 26-stellige ULID. Diese ID:

  • ist garantiert eindeutig pro Shop,

  • ist nicht aus der internen Datenbank-ID ableitbar,

  • ist nicht enumerierbar (man kann nicht durch Hochzählen weitere Benutzer finden),

  • erfordert kein konfiguriertes Pflichtfeld am Benutzer.

Beispiel: /page/01HV2XKQP4MNRST8WQZJ6BYDE/pizzeria-venezia

Wann verwenden? Im Zweifelsfall immer. Sicher per Default.

Option B: Aus einem Benutzerfeld ableiten (opt-in)

Statt einer ULID wird der Wert eines Benutzerfelds (z.B. customer_user_kundennummer) URL-tauglich normalisiert und als Prefix benutzt. Vorteil: sprechender URL. Nachteile: erratbar (sequentielle Kundennummern!), kann doppelt vorkommen, kann leer sein.

Beispiel: /page/854121/pizzeria-venezia

Wann verwenden? Nur wenn der Kunde ausdrücklich wünscht, dass z.B. seine Kundennummer in der URL erscheint, und er das Enumerations-Risiko akzeptiert. In allen anderen Fällen Option A.

Wird Option B gewählt, erscheint zusätzlich das Feld „Benutzerfeld für die öffentliche Benutzer-ID" mit allen verfügbaren SSO-Benutzerfeldern zur Auswahl.

Schritt 5: Hinweis-Panel beachten

Sobald in Option B ein Feld ausgewählt wird, prüft das System sofort und live drei Dinge:

  1. Pflichtfeld? – Ist das gewählte Feld im Shop als Pflichtfeld konfiguriert? Wenn nicht, kann es Benutzer ohne ausgefüllten Wert geben → kein Prefix möglich.

  2. Eindeutig? – Gibt es im Shop bestehende Benutzer, bei denen dasselbe Feld doppelt vorkommt? Diese Benutzer würden sich denselben URL-Prefix teilen.

  3. Vollständig befüllt? – Gibt es Benutzer, bei denen das Feld leer ist? Diese bekommen noch keine Landingpage-URL.

Treffer werden über dem Formular in einem gelben Hinweis-Panel angezeigt – persistent, solange das Problem besteht. Der Hinweis bleibt auch nach Reload sichtbar; er verschwindet erst, wenn die Ursache behoben ist.

Wichtig: Das Panel zeigt den aktuellen Stand schon vor dem Speichern. Es reicht, das Feld auszuwählen – der Admin sieht sofort, ob die gewählte Konfiguration tragfähig ist.

grafik-20260422-131541.png

 

Beispiel-Meldungen

Hinweis: Das Feld "customer_user_kundennummer" ist im Shop nicht als Pflichtfeld konfiguriert. Damit kann es Benutzer ohne öffentliche ID geben und neue Benutzer lassen das Feld möglicherweise leer. Achtung: Das Feld "customer_user_kundennummer" ist bei 2 Wert(en) doppelt im Shop vorhanden. Diese Benutzer würden sich denselben URL-Prefix teilen. Hinweis: 17 Benutzer haben das Feld "customer_user_kundennummer" noch nicht befüllt und bekommen so noch keine eigene Landingpage-URL.

Wo behebe ich das?

Meldung

Lösung

Meldung

Lösung

„nicht als Pflichtfeld konfiguriert"

Im Backend unter Shops → Bearbeiten → Benutzereinstellungen → Pflichteingaben für Benutzerfelder das entsprechende Feld auf „Pflicht (Ja)" stellen.

„doppelte Werte"

Über die Benutzersuche bzw. Export die Duplikate finden und bereinigen. Erst danach speichern.

„noch nicht befüllt"

Bestehende Benutzer dazu bringen, das Feld auszufüllen (z.B. erzwungenes Update beim nächsten Login).

Schritt 6: Vorschlag für den Landingpage-Namen

Optional: Über „Benutzerfeld als Vorschlag für den Landingpage-Namen" kann ein Feld ausgewählt werden, dessen Wert beim automatischen Anlegen einer Landingpage als initialer Name (Slug) vorgeschlagen wird.

Beispiel:

Einstellung

Wert

Einstellung

Wert

Vorschlagsfeld

customer_user_company1

Benutzer-Wert

Pizzeria Venezia GmbH

Generierter Slug

pizzeria-venezia-gmbh

Sonderzeichen, Leerzeichen und Großbuchstaben werden automatisch entfernt bzw. ersetzt. Der Shop-Benutzer kann den Slug danach jederzeit selbst ändern.

Wird kein Feld gewählt, muss der Benutzer den Namen beim ersten Aufruf der Verwaltung selbst eingeben.

Schritt 7: Wann wird eine Landingpage erzeugt?

Die Landingpage eines Shop-Benutzers wird bei Bedarf angelegt — es gibt keine separate Konfiguration mehr dafür. Auslöser sind:

  1. Erster Aufruf der Shop-Verwaltungsseite durch den Benutzer (über das Konto-Menü).

  2. Erster Aufruf des Printess-Editors für einen Artikel mit konfigurierter Printess-Feld-Zuordnung (siehe Schritt 9 unten) — die Landingpage muss vorhanden sein, damit ihre URL und ihr Name ins Personalisierungs-Formular fließen können. Greift sowohl beim normalen Editor-Aufruf als auch beim Re-Editieren einer freigegebenen Bestellung, solange das Order-Item noch nicht personalisiert wurde.

Vorteile dieses Ansatzes: keine „leeren" Landingpages für Benutzer, die das Modul nie nutzen; kein nachträglicher Backfill nötig; keine Race-Conditions mit SSO-Pflichtfeldern, die erst beim ersten Login befüllt werden.

Schritt 8: Speichern

Beim Speichern passieren mehrere Dinge:

  1. Die Einstellungen werden in customer_settings.value als JSON unter dem Schlüssel digitalProductPageModule abgelegt.

  2. Der Cache für die Sichtbarkeit des Shop-Menüpunkts wird invalidiert (<clientId>_digitalProductPageAdminMenuEnabled_<shopId>).

  3. Die Validierung läuft erneut. Treten Hinweise auf, werden sie doppelt ausgegeben:

    • als gelbes Toastr unten rechts (kann manuell weggeklickt werden),

    • als Eintrag im Notification-Center,

  4. Das Hinweis-Panel über dem Formular aktualisiert sich automatisch — wenn ein Problem gerade behoben wurde, verschwindet es; ein neues bleibt sichtbar.

Nightly Validierungs-Cronjob

Auch nach dem Speichern können neue Probleme entstehen — zum Beispiel:

  • Ein neuer Benutzer wird per SSO angelegt, das Pflichtfeld wird vom Identity-Provider nicht mitgeliefert.

  • Ein Import erzeugt zwei Benutzer mit derselben Kundennummer.

  • Der Admin entfernt versehentlich das Pflichtfeld-Flag im Shop.

Damit das nicht unbemerkt bleibt, läuft jeden Tag um 04:00 Uhr ein Cronjob.

Der Cronjob:

  1. liest alle Shops mit gespeicherten DigitalProductPage-Einstellungen,

  2. filtert auf aktive Module,

  3. ruft pro Shop dieselbe validatePrefixField()-Logik wie das Backend-Form,

  4. legt bei Treffern eine Notification (Glocke) an und benachrichtigt den technischen Ansprechpartner per Mail.

So gibt es drei aufeinanderfolgende Stufen:

Wann

Wo sichtbar

Persistenz

Wann

Wo sichtbar

Persistenz

Beim Tippen im Form

Hinweis-Panel

Solange das Problem besteht

Beim Speichern

Toast + Notification + Mail

Bis manuell weggeklickt / archiviert

Nightly Cron

Notification + Mail

Bis behoben

Printess-Feld-Zuordnung pro Artikel

Damit aus der Personalisierung ein Landingpage-Name, ein Tab-Name und optional ein Header-Medium wird, können am Artikel vier Printess-Formularfelder zugeordnet werden. Im Backend unter Artikel → Bearbeiten → Tab „Grundeinstellungen" erscheint der Block „Digital-Landingpage: Printess-Feld-Zuordnung" sobald für den Mandanten DigitalProductPage und Printess beide aktiv sind und im Artikel ein Printess-Template ausgewählt wurde.

Die vier Felder

Setting

Inhalt im Editor

Verwendung

Setting

Inhalt im Editor

Verwendung

Printess-Feld für die Landingpage-URL

Wird beim Öffnen mit <https://<shop>>/page/{öffentliche Benutzer-ID}/ vorbefüllt. Im Printess-Template als nicht editierbar konfigurieren.

Reine Anzeige für den Benutzer; verändert nichts.

Printess-Feld für den Landingpage-Namen

Editierbar. Beim Öffnen mit dem aktuellen Namen (Slug) der (ggf. neu angelegten) Default-Landingpage vorbefüllt.

Wird beim erstellter Bestellung (nach Freigaben) ausgelesen: weicht der Wert vom aktuellen Namen (Slug) ab, wird die Landingpage automatisch umbenannt (alter Slug wird zur Historie und löst eine Weiterleitung aus). Bei Slug-Kollision (Name bereits vergeben oder in fremder Historie reserviert) wird der Rename übersprungen und ein Warnung geloggt.

Printess-Feld für den Tab-Namen

Editierbar. Beim Öffnen leer.

Wird beim erstellter Bestellung (nach Freigaben) als neuer Tab unterhalb der Landingpage angelegt. Bei Nachbestellungen wird der alte Tab per Soft-Delete abgelöst und ein neuer Tab mit dem aktuellen Inhalt erstellt. Bei Slug-Kollision mit einem bestehenden Tab bekommt der neue Tab ein Datums-Suffix (z.B. mittag-new-2026-04-15-143200) — der Shop-Benutzer kann den alten Tab anschließend in der Verwaltung per Ein-Klick-Aktion ersetzen.

Printess-Feld für das Header-Medium

Editierbar. Beim Öffnen leer. Typischerweise ein Freitext-Feld, das im Printess-Template an einen Bild- oder Video-Picker gekoppelt ist.

Wird beim erstellter Bestellung (nach Freigaben) ausgelesen: der zurückgegebene URL-Wert wird per HEAD-Request auf image/* oder video/* geprüft und auf der Landingpage als Banner des zu diesem Bestellposition gehörenden Tabs angezeigt — überschreibt Artikel- und Shop-Defaults. Siehe Abschnitt Header-Medien konfigurieren.

Welche Printess-Felder erscheinen in der Auswahl?

Es werden nur Freitext-Formularfelder des aktuell ausgewählten Templates angeboten. Listen-Felder werden ausgeblendet, weil sie nur fest vordefinierte Werte akzeptieren und sich daher nicht für einen individuellen Namen oder eine URL eignen. Eine Info-Box oberhalb der Auswahl zeigt, wie viele Felder ausgeblendet wurden (z.B. „12 von 232 Feldern nutzbar · 220 Listen-Felder ausgeblendet").

Die Form-Felder werden von Printess abgefragt und 5 Minuten pro Shop-Template gecached. Der Cache-Status (frisch / stale / API nicht erreichbar) wird unterhalb der Selects als kleiner Hinweis angezeigt; bei totalem API-Ausfall ohne Cache fällt die Auswahl auf reine Texteingabe-Felder zurück, damit die Bearbeitung nicht blockiert.

Was passiert beim Öffnen des Editors?

  1. Modul aktiv für den Mandanten + Modul aktiv für den Shop + mindestens eines der drei Felder gemappt? Sonst passiert nichts.

  2. Hat der Shop-Benutzer noch keine Landingpage? → eine neue wird lazy angelegt (gleicher Pfad wie beim ersten Aufruf der Shop-Verwaltungsseite).

  3. Wenn es mehr als eine Landingpage gibt, wird die als Standard markierte ausgewählt.

  4. URL <https://<shop>>/page/{prefix}/ und der Name (Slug) der Landingpage werden als Initialwerte in templateFormFields an Printess übergeben.

Greift sowohl beim normalen Editor-Aufruf als auch beim Re-Editieren einer freigegebenen Bestellung, solange die Bestellposition noch nicht personalisiert wurde. Bei bereits personalisierten Bestellpositionen (Cart-Edit, Reorder, Save-Token-Load, Übernahme aus anderer Position) wird nicht überschrieben — der Kunde behält den von ihm zuvor gewählten Namen (Slug).

Koexistenz mit dem alten DigitalProduct

Wenn am selben Mandanten zusätzlich DigitalProduct aktiv ist, erscheint dessen alter Block oberhalb der DigitalProductPage-Sektion. Beide funktionieren unabhängig voneinander — pro Artikel wird typischerweise nur eines der beiden Module genutzt, die UI erzwingt das aber nicht.

Info-Bereich konfigurieren

Der Info-Bereich auf der öffentlichen Landingpage zeigt standardmäßig Firmenname, Adresse und Kontaktblock direkt aus den Benutzerstammdaten. Über die Modul-Konfiguration können zusätzlich bis zu acht weitere Inhalte freigeschaltet werden — pro Slot wird ein Benutzerfeld zugeordnet, das den Wert liefert.

[Screenshot: Modul-Konfigurationsseite – Abschnitt „Info-Section Felder zuordnen"]

Verfügbare Slots

Slot

Inhalt auf der Landingpage

Empfohlener Feldtyp

Slot

Inhalt auf der Landingpage

Empfohlener Feldtyp

Logo

Bild oben in der Info-Spalte. Wird über eine signierte, dauerhaft cachebare URL ausgeliefert.

Bildfeld (Dynamisches Benutzerfeld)

Zahlungsarten

Reihe farbiger Pill-Tags. Kommagetrennte Werte werden zu einzelnen Tags.

Tags (Dynamisches Benutzerfeld)

Zusatzinfo 1, Zusatzinfo 2, Zusatzinfo 3

Drei freie Blöcke mit eigener Überschrift und Freitext. Pro Block eigenständig zuordbar.

Eingabefeld oder Mehrzeiliges Eingabefeld

Öffnungszeiten (Mo–So)

Tabelle mit pro Wochentag zuordbarem Eintrag. Heutige Zeile wird automatisch hervorgehoben.

Eingabefeld pro Wochentag

Social-Media (Instagram, Facebook, TikTok, LinkedIn, YouTube, X, Pinterest, WhatsApp)

Reihe runder Icon-Buttons. Pro Plattform individuell zuordbar.

URL (Dynamisches Benutzerfeld) — Ausnahme WhatsApp: hier darf auch ein gewöhnliches Eingabefeld mit der Telefonnummer verwendet werden, die wa.me-URL wird automatisch zusammengebaut

Slots zuordnen

In der Modul-Konfigurationsseite gibt es im Abschnitt „Info-Section Felder zuordnen" pro Slot eine Auswahlliste. Die Liste ist zweigeteilt:

  1. Statische SSO-Benutzerfelder (z.B. „Telefon", „Webseite") — direkte Stammdaten, die jeder Benutzer ausgefüllt haben kann.

  2. Dynamische Benutzerfelder des Shops, gruppiert nach Feldtyp (Eingabefeld, Tags, Bildfeld, …).

Dynamische Benutzerfelder werden in einem separaten Modul gepflegt — Konfigurationspfad und alle verfügbaren Feldtypen sind in Dynamische Benutzerfelder beschrieben. Sind die für den Info-Bereich gewünschten Feldtypen (insbesondere Tags und URL für Social-Media-Profile) noch nicht angelegt, müssen sie dort vor der Zuordnung im DPP-Modul erstellt werden.

Slots, die auf „— Nicht zuordnen —" stehen, werden auf der Landingpage komplett unterdrückt — kein leerer Block, kein Trenner, keine Überschrift.

Reihenfolge auf der Landingpage

Die Reihenfolge im Info-Bereich ist fest:

  1. Logo (falls Wert vorhanden)

  2. Firma + Adresse + Kontakt (direkt aus den Stammdaten)

  3. Maps-Links (automatisch, sobald Straße + Ort vorhanden)

  4. Öffnungszeiten (falls mindestens ein Wochentag gemappt und gefüllt)

  5. Zahlungsarten (falls Wert vorhanden)

  6. Zusatzinfo 1 / 2 / 3 (jeder Block einzeln, falls Wert vorhanden)

  7. Social-Media-Icons (falls mindestens eine Plattform gemappt und gefüllt)

Tabs im Mapping ändern nur, welche Slots Inhalt bekommen — die Reihenfolge auf der Seite ist kein Konfigurationsparameter.

Maps-Links

Sobald Straße und Ort beim Shop-Benutzer ausgefüllt sind, erscheinen unter der Adresse zwei Pin-Buttons: Auf Google Maps öffnen und In Apple Maps öffnen. Der Server rendert beide Links in das HTML; ein kleiner Inline-JavaScript-Block setzt direkt vor dem Block die CSS-Klasse is-apple auf das <html>-Element, sobald der Browser ein iOS-, iPadOS- oder macOS-Gerät meldet. Die CSS blendet den jeweils passenden Link aus, sodass Apple-Geräte den Apple-Maps-Link sehen und alle anderen Geräte den Google-Maps-Link.

Es gibt keine Pflicht, etwas zu konfigurieren — der Block erscheint automatisch, sobald Straße und Ort vorhanden sind.

WhatsApp-Spezialfall

Beim Slot Social-Media → WhatsApp baut die Landingpage die <https://wa.me/<Nummer>>-URL automatisch zusammen. Der Shop-Benutzer kann seine Nummer in lesbarer Form eingeben — Leerzeichen, Bindestriche, Klammern und ein führendes „00" oder „+" werden beim URL-Aufbau entfernt. Trägt der Benutzer bereits eine fertige <https://wa.me/...-URL> ein, wird diese unverändert übernommen.

Empfehlung: das WhatsApp-Feld als gewöhnliches Eingabefeld anlegen (nicht als URL-Feld) — sonst weist die Browser-Validierung eine reine Telefonnummer als „keine URL" ab.

Sprachschlüssel und Personalisierung der Überschriften

Alle Überschriften und sichtbaren Texte des Info-Bereichs sind über die Shop-Sprachverwaltung pro Shop überschreibbar. Damit kann z.B. der Block „Zahlungsarten" für einen italienischen Shop in „Pagamenti accettati" umbenannt werden, ohne dass die anderen Shops davon betroffen sind. Im Modul-Konfigurations-Bildschirm erscheint unterhalb jeder Zusatzinfo-Auswahl der zugehörige Sprachschlüssel als kopierbarer Codeblock.

Übersicht der wichtigsten Schlüssel:

Schlüssel

Default

Wirkung

Schlüssel

Default

Wirkung

dpp_infoSection_paymentMethods

„Zahlungsarten" / „Payment methods"

Überschrift des Zahlungsarten-Blocks

dpp_infoSection_openingHours

„Öffnungszeiten" / „Opening hours"

Überschrift der Öffnungszeiten-Tabelle

dpp_infoSection_closed

„Geschlossen" / „Closed"

Wird an Wochentagen ohne Wert angezeigt

dpp_infoSection_socialLinks

„Social Media" / „Social media"

Überschrift des Social-Media-Blocks

dpp_infoSection_additionalInfo1

„Info"

Überschrift des ersten Zusatzinfo-Blocks

dpp_infoSection_additionalInfo2

„Info"

Überschrift des zweiten Zusatzinfo-Blocks

dpp_infoSection_additionalInfo3

„Info"

Überschrift des dritten Zusatzinfo-Blocks

dpp_infoSection_openInGoogleMaps

„Auf Google Maps öffnen" / „Open in Google Maps"

Beschriftung des Google-Maps-Buttons

dpp_infoSection_openInAppleMaps

„In Apple Maps öffnen" / „Open in Apple Maps"

Beschriftung des Apple-Maps-Buttons

dpp_infoSection_day_mondaydpp_infoSection_day_sunday

„Montag" … „Sonntag" / „Monday" … „Sunday"

Wochentag-Beschriftungen in der Öffnungszeiten-Tabelle

dpp_infoSection_socialPlatform_<name> (8 Plattform-Schlüssel)

Plattform-Name

Wird als aria-label der Icon-Buttons verwendet (für Screenreader und Accessibility)

Die Sprachverwaltung des Shops finden Sie im Shop-Menüpunkt für Übersetzungen. Dort den Schlüssel suchen und den eigenen Wert eintragen — Änderungen wirken sofort, kein Deploy nötig.

Personalisierung über CSS

Die öffentliche Landingpage liefert ein Standard-Design, das auf einen dunklen, mobil-optimierten Look ausgelegt ist. Für individuelle Anpassungen pro Shop (Brand-Farbe, andere Hervorhebung, andere Akzente) gibt es eine Reihe stabiler CSS-Klassen, die Sie in der Shop-Custom-CSS überschreiben können — ohne dass das Template angefasst werden muss. Die folgenden Klassen sind als Personalisierungs-Hooks gedacht und werden nicht ohne Vorankündigung umbenannt.

Allgemeine Info-Bereich-Klassen

Klasse

Wann gesetzt

Typische Verwendung

Klasse

Wann gesetzt

Typische Verwendung

.dpp-info-section

Container des gesamten Info-Bereichs

Hintergrund, Innenabstand, Schriftart

.dpp-info-block

Einzelner Block (Adresse, Logo, …)

Vertikaler Abstand zwischen Blöcken

.dpp-info-divider

Trenner zwischen zwei Blöcken

Linienfarbe, Linienstärke, ausblenden

.dpp-info-label

Überschrift jedes Blocks

Schriftfarbe und -größe

Logo

Klasse

Verwendung

Klasse

Verwendung

.dpp-info-logo-block

Container des Logo-Blocks

.dpp-info-logo-block img

Das eigentliche Bild — Default max-height: 120px, object-fit: contain

Öffnungszeiten

Klasse

Wann gesetzt

Default

Klasse

Wann gesetzt

Default

.dpp-info-hours

Tabellen-Container

.dpp-info-hours-row

Jede Tabellenzeile

.dpp-info-hours-row--monday--sunday

Pro Wochentag

.dpp-info-hours-row--open

Tag mit hinterlegter Zeit

.dpp-info-hours-row--closed

Tag ohne Zeit

opacity: 0.5 (ausgegraut)

.dpp-info-hours-row--today

Aktueller Wochentag (Server-Zeit)

font-weight: bold

.dpp-info-hours-day