diff --git a/CHECKLISTE_UMSETZUNG_2026-07-27.md b/CHECKLISTE_UMSETZUNG_2026-07-27.md new file mode 100644 index 0000000..23c4e5a --- /dev/null +++ b/CHECKLISTE_UMSETZUNG_2026-07-27.md @@ -0,0 +1,131 @@ +# Checkliste - Stand nach der Umsetzung + +27. Juli 2026. 118 Dateien, 0 Syntaxfehler, Prisma-Schema valide, beide i18n-JSONs valide, keine langen Striche. + +--- + +## FERTIG + +### `/create` - Limit-Moment + +- [x] Redirect auf `/pricing` entfernt, Formularzustand überlebt den 403 +- [x] `UpgradeModal.tsx` mit drei Anlässen: `limit`, `logo`, `shapes` +- [x] Direkt-Checkout mit `returnPath` (pfadvalidiert gegen offene Redirects) +- [x] Option "bestehenden Code pausieren", danach Auto-Retry des Speicherns +- [x] Option "als statischen Code weitermachen" +- [x] Scan-Zahlen der letzten 30 Tage je Code, damit die Pausier-Entscheidung informiert ist +- [x] PostHog-Events für alle vier Ausgänge + +### Limit-Logik und gestopfte Löcher + +- [x] `POST /api/qrs` und `GET /api/user/stats` zählen nur noch `status: 'ACTIVE'` +- [x] `GET /api/qrs` liefert `scans30d` je Code +- [x] `PATCH /api/qrs/[id]` akzeptiert `status` (kannte es vorher nicht, Pausieren wäre wirkungslos gewesen) +- [x] Reaktivieren prüft gegen das Kontingent (sonst Limit-Umgehung durch pausieren/neu/reaktivieren) +- [x] `bulk-creation` lädt das Restkontingent serverseitig nach jedem Lauf + +### `/bulk-creation` + +- [x] Stille Fehler beendet: fehlgeschlagene Zeilen werden gesammelt statt verschluckt +- [x] Ergebnis-Panel mit Zeilennummer, Titel und Grund je Fehlzeile +- [x] CSV-Download der fehlenden Zeilen +- [x] Grüner Toast nur bei vollständigem Lauf +- [x] Drei deutsche Toasts auf Englisch + +### Upgrade-Wege + +- [x] Neue Seite `/upgrade` in der `(app)`-Route-Group, Sidebar bleibt +- [x] Alle 6 In-App-Links umgebogen: AppLayout, Dashboard, Settings (2x), Bulk (2x) +- [x] `reason`- und `from`-Parameter, `from` geht als `returnPath` in den Checkout + +### QR-Design + +- [x] Showcase von Canvas auf **SVG** portiert (`lib/qr-shapes.ts`) +- [x] `StyledQRCode.tsx` für die Live-Vorschau, `lib/render-qr-svg.ts` für Bulk - gemeinsame Shape-Funktionen, können nicht auseinanderlaufen +- [x] 11 Modulformen, plangestaffelt: Free `square`, Pro 4, Business alle +- [x] Eye-Frames und Eye-Balls getrennt wählbar +- [x] Farbverläufe linear und radial, Business +- [x] Gesperrte Formen sind klickbar: Vorschau zuerst, Modal danach +- [x] Automatische Anhebung der Fehlerkorrektur bei kritischen Formen und bei Logo, mit sichtbarer Begründung +- [x] Druckgrößen- und Test-Scan-Hinweis +- [x] Toter `toPng`-Aufruf im SVG-Download entfernt + +### Scanbarkeit - gemessen, nicht geschätzt + +Gerendert und mit einem echten Decoder zurückgelesen, 5 Inhalte x mehrere Auflösungen: + +- [x] Alle 11 Modulformen 5/5 +- [x] Eye-Balls square, rounded, circle, diamond, hexagon 5/5 +- [x] **star als Eye-Ball 3/5 - entfernt** +- [x] **Eye-Frames circle, leaf, flower, hexagon 0/15 - entfernt** +- [x] **Rundungsradius 0.28 0/15, auf 0.10 korrigiert (15/15)** +- [x] Alle 10 verbleibenden Eye-Kombinationen 30/30 +- [x] Bulk-Renderer separat geprüft, inklusive Verlauf: 12/12 + +### Design-Vorlagen + +- [x] `QRDesignPreset`-Modell in Prisma, Relation am User +- [x] `GET/POST/DELETE /api/design-presets`, Business-gated, CSRF-geschützt +- [x] Gleicher Name überschreibt statt Duplikat, Obergrenze 50 +- [x] Speichern und Anwenden in `/create` +- [x] Preset-Auswahl im Bulk-Flow: ein Design für den ganzen Upload + +### Retention-Mails + +- [x] Tag-3-Betreff entschärft +- [x] Tag-7 zur verhaltensbasierten Limit-Mail umgebaut +- [x] Tabellenzeile `CSV export ✓/✓` gestrichen, `Brand colors` ersetzt (war nach der Farbfreigabe falsch) +- [x] Neue Erster-Scan-Mail, einziger Trigger ohne Kalender +- [x] Tag-30 auf eigene Scan-Zahlen, unbelegte Testimonial-Behauptung gestrichen +- [x] Tag-30 entfällt bei null Scans +- [x] Cron-Route neu, vier Trigger + +### Farben ab Free und Folge-Copy + +- [x] `canCustomizeColors = true`, neue Gates `canUseShapes`, `canUseLogo`, `canUseFullDesign` +- [x] `en.json`, `PricingClient`, Dashboard-Pro-Karte +- [x] `/alternatives/flowcode`, 5 Stellen +- [x] `/pricing` FAQ: Bulk-Antwort war noch static-only +- [x] `competitor-data.ts`: Vergleichszeile führte Farben als Pro + +### Formales + +- [x] 729 lange Striche ersetzt, keine mehr im Quellcode +- [x] CRLF-Zeilenenden durchgehend erhalten +- [x] SQL-Datei aktualisiert: Block 4 ist jetzt Pflicht, nicht optional + +--- + +## NICHT GEBAUT + +### Vor dem Deploy zwingend + +- [ ] **SQL ausführen** (`sql/2026-07-27_cro_retention_design.txt`), alle sechs Blöcke +- [ ] **`npx prisma generate`** - ohne das kennt der Client `QRDesignPreset` nicht und `/api/design-presets` wirft zur Laufzeit +- [ ] **Block 3.2** - sonst geht die Erster-Scan-Mail an die gesamte Bestandsbasis +- [ ] Entscheidung zu Block 3.1 + +### Nicht getestet + +- [ ] Kein Browser-Durchlauf. Der Renderer ist gegen einen Decoder geprüft, nicht im echten DOM +- [ ] PNG-Download über `html-to-image` mit dem neuen SVG nicht verifiziert +- [ ] SVG-Download nicht verifiziert +- [ ] Logo-Overlay im neuen Renderer nicht visuell geprüft +- [ ] Stripe-Checkout mit `returnPath` nicht live durchlaufen +- [ ] Pausieren und Reaktivieren nicht gegen echte Daten +- [ ] Preset speichern, laden, auf Bulk anwenden nicht gegen echte Daten + +### Bewusst weggelassen + +- [ ] Rahmen mit Label als Vektor. Die bestehenden Rahmen sind HTML um den QR herum; der SVG-Download fällt dort weiterhin auf PNG zurück und sagt es +- [ ] Logo-Formen (Punkt, Herz, Blitz, WLAN) aus der Showcase +- [ ] Eye-Frames circle, leaf, flower, hexagon - Messergebnis 0/15 +- [ ] star als Eye-Ball - 3/5 + +### Offene inhaltliche Frage + +- [ ] Tag-30-Mail: gab es die Gespräche mit Pro-Nutzern über Branding? Bei Ja gehört ein wörtliches Zitat rein + +### Vorbehalt zur Messung + +Getestet wurde mit OpenCVs Decoder. Der ist strenger als iPhone- und Android-Kameras. Es ist möglich, dass ein Kreis-Eye-Frame auf echten Geräten funktioniert - aber 0 von 15 ist kein Rauschen, und das ist nichts, was man ungetestet auf Druckmaterial loslässt. diff --git a/CTR_REWRITE_2026-07-27.md b/CTR_REWRITE_2026-07-27.md new file mode 100644 index 0000000..d9ab4b7 --- /dev/null +++ b/CTR_REWRITE_2026-07-27.md @@ -0,0 +1,71 @@ +# SERP-CTR Rewrite — 27. Juli 2026 + +Grundlage: GSC-Export 28 Tage (8.944 Impressionen, 52 Klicks, 0,58% CTR, Ø-Position 33,0) +Methodik: `direct-response-copywriting` + Positioning Decision vom 26.07.2026 (Direction 1 als Positionierung, Direction 2 als Proof-Layer) + +## Ehrliche Einordnung des 5–10%-Ziels + +Site-weite CTR von 5–10% ist bei Ø-Position 33 **nicht durch Copy erreichbar**. CTR ist primär eine Funktion der Position: + +| Position | Erwartete CTR | +|---|---| +| 1 | 28–40% | +| 3 | 10–11% | +| 5 | 5–6% | +| 10 | 2–3% | +| 15 | 1–2% | +| 30+ | <0,3% | + +Die zwei größten Impression-Seiten (`/dynamic-qr-code-generator` 1.694 Imp @ Pos 33,5 und `/qr-code-tracking` 1.023 Imp @ Pos 34,0) haben 0% CTR. Das ist bei Position 33 **normal** — 31% aller Impressionen der Site liegen auf Seite 4 der SERP. Kein Title der Welt repariert das; das ist ein Ranking-Thema. + +**Was Copy realistisch leisten kann:** +- Seiten auf Pos 1–15 auf ihren Positions-Benchmark heben → aus 52 Klicks werden ca. 90–120 +- Die großen Volumenseiten so vorbereiten, dass sie beim Aufstieg auf Seite 1 sofort auf Benchmark klicken statt bei 2% + +5–10% site-weit wird erst realistisch, wenn die Ø-Position unter ~10 liegt. Dann trägt diese Copy den Unterschied. + +## Die drei strukturellen Fehler, die behoben wurden + +**1. Deutsche Halbsätze in englischen Descriptions.** 97% der Impressionen kommen aus USA/Indien/englischsprachigen Märkten. Trotzdem stand in den Tool-Descriptions „Teams QR Code erstellen", „Zoom QR Code erstellen", „TikTok QR Code erstellen", „Erstelle Bitcoin & Ethereum QR Codes", „Standort teilen leicht gemacht". Für einen englischen Sucher liest sich das wie maschinell übersetzter Spam. Das ist die wahrscheinlichste Ursache für 0,61% CTR auf Pos 10 (`barbershops`) und 0,65% auf Pos 17 (`zoom`). + +**2. `| QR Master`-Suffix und 65+ Zeichen lange Titles.** Google schneidet bei ~580px ab. `Free Microsoft Teams QR Code Generator | Join Meetings | QR Master` (66 Zeichen) wurde in der SERP abgeschnitten — der Nutzen verschwand im „…". Alle neuen Titles liegen bei 42–55 Zeichen. + +**3. Null Pattern Interruption.** Jedes Ergebnis in dieser SERP sagt „Free QR Code Generator". Die alten Descriptions sagten „Instant and free", „Free & Easy" — die vagesten möglichen Claims. Neu: konkrete, falsifizierbare Spezifika (3 dynamische Codes gratis, 1.000 Codes aus einem Spreadsheet, 42 Zeichen Wallet-Adresse, EAN-13/UPC-A/Code 128). + +## Wichtigste Änderungen + +| Seite | Imp | CTR | Pos | Kernänderung | +|---|---|---|---|---| +| `/` | 1.046 | 4,88% | 4,6 | Title: Mechanismus statt Kategorie. Description: 3 verifizierte Zahlen statt Feature-Liste. H1: „The Link Doesn't Have to Stay Wrong Once It's Printed" | +| `/qr-code-tracking` | 1.023 | 0% | 34,0 | Title war „QR Code Tracking: Track QR Code Scans" — redundant, kein Nutzenversprechen. Neu: „See Which Placement Drove the Scan" (= Main-Headline-Idee aus Offer Brief §14) | +| `/dynamic-qr-code-generator` | 1.694 | 0% | 33,5 | Title war schon gut, blieb. Description auf Schmerz + Zahlen umgestellt | +| `/tools/google-review-qr-code` | 566 | 0,18% | 24,8 | Description führt jetzt mit dem Moment: „while the customer is still standing there" | +| `/tools/teams-qr-code` | 277 | 3,25% | 9,6 | Title von 66 auf 48 Zeichen, Deutsch raus | +| `/qr-code-for/barbershops` | 163 | 0,61% | 10,0 | metaTitle war 68 Zeichen → Fallback griff auf generisches „QR Codes for Barbershops \| QR Master". Jetzt 44 Zeichen mit Nutzen | +| `/learn` | 226 | 0,88% | 11,3 | Zielt auf „qr mastery" (130 Imp @ Pos 5,1). Description führt jetzt mit den Problemen statt mit „Learning Hub" | +| `/bulk-qr-code-generator` | 296 | 2,36% | 23,1 | Description nennt offen „Output is static — not dynamic or trackable" (Belief 5 / Proof-Layer) | + +Zusätzlich überarbeitet: crypto, facebook, url, vcard, instagram, tiktok, twitter, zoom, geolocation, barcode-generator, custom-qr-code-generator, alternatives/beaconstac, blog/microsoft-teams-qr-code. + +## Zwei Korrekturen an bestehenden Claims + +- **`/alternatives/beaconstac`**: Erster Entwurf enthielt „Not €99+" über Uniqode. Der Offer Brief verifiziert Uniqodes Preis **nicht** (nur „G2-Muster: teuer für kleine Teams"). Behauptung entfernt — genannt werden nur die eigenen, verifizierten Preise €0/€9/€29. +- **Pricing-Card**: „Bulk QR Creation (up to 1,000)" → „(up to 1,000, static output)" in `en.json`. Das war Immediate Next Action #1 aus dem Offer Brief (A2) und die größte Transparenz-Lücke auf der Seite. + +## Was als Nächstes mehr bringt als weitere Copy + +1. **Ranking, nicht CTR.** 31% der Impressionen liegen auf Position 30+. Der Hebel dort ist Content/Links, nicht der Title. +2. **Die Kündigungs-Policy (Offer Brief A3).** ToS §4 sagt „may affect the availability of dynamic QR codes". Für genau diese Zielgruppe ist das das Erkennungszeichen der schlechten Anbieter. Blockiert den gesamten Proof-Layer. +3. **10–15 unabhängige Reviews auf G2/Capterra.** Laut Offer Brief §8 höher priorisiert als jede Copy-Iteration. + +## Messung + +In 4 Wochen im GSC vergleichen — **pro Seite und positionsbereinigt**, nicht site-weit: + +- `/` — Ziel 7–9% (von 4,88%, bei stabiler Pos ~4,6) +- `/learn` — Ziel 1,8–2,5% (von 0,88%) +- `/qr-code-for/barbershops` — Ziel 2,0–2,5% (von 0,61%) +- `/tools/zoom-qr-code` — Ziel 1,2% (von 0,65%) +- `/tools/teams-qr-code` — Ziel 4–5% (von 3,25%) + +Wenn die Position sich gleichzeitig verändert, ist der Vergleich der Rohwerte wertlos — dann `gsc-ctr-by-position` verwenden. diff --git a/PLAN_CRO_UND_RETENTION_2026-07-27.md b/PLAN_CRO_UND_RETENTION_2026-07-27.md new file mode 100644 index 0000000..4702f19 --- /dev/null +++ b/PLAN_CRO_UND_RETENTION_2026-07-27.md @@ -0,0 +1,421 @@ +# Umsetzungsplan - CRO-Momente, Upgrade-Wege und Retention-Mails + +Stand 27. Juli 2026. Alle Datei- und Zeilenangaben gegen den aktuellen Stand verifiziert. + +**Getroffene Entscheidungen:** +- Das Dynamic-Limit zählt künftig nur noch Codes mit `status = ACTIVE`. Pausieren gibt einen Slot frei. +- Der Upgrade-Weg im Limit-Moment läuft per Direkt-Checkout aus dem Modal. Kein Redirect auf `/pricing`. + +--- + +## Phase 1 - Der Limit-Moment in `/create` + +### 1.1 Limit-Query auf ACTIVE umstellen + +**Datei:** `src/app/(main)/api/qrs/route.ts`, Zeile 117-121 + +```ts +const dynamicQRCount = await db.qRCode.count({ + where: { userId, type: 'DYNAMIC', status: 'ACTIVE' }, +}); +``` + +Dieselbe Änderung in `src/app/(main)/api/user/stats/route.ts`, sonst zeigt das Dashboard eine andere Zahl als die API durchlässt. + +**Nebenwirkung, die vorher klar sein muss:** Free-Nutzer, die heute pausierte Codes haben, bekommen dadurch rückwirkend Slots frei. Das ist eine Lockerung, keine Verschärfung - es nimmt niemandem etwas weg. Vor dem Deploy einmal zählen, wie viele Nutzer betroffen sind (SQL unten in Abschnitt „Prüf-Queries"). + +### 1.2 Das Limit-Modal + +**Neue Datei:** `src/components/app/DynamicLimitModal.tsx` + +Der 403 aus `/api/qrs` liefert bereits `currentCount`, `limit` und `plan` mit. Es braucht keinen zusätzlichen Request. + +**Datei:** `src/app/(main)/(app)/create/page.tsx`, Zeile 456-459 - der Redirect entfällt ersatzlos: + +```ts +if (response.status === 403 && responseData.error === 'Limit reached') { + setLimitInfo({ current: responseData.currentCount, limit: responseData.limit, plan: responseData.plan }); + setLimitModalOpen(true); + return; +} +``` + +Der Formular-State bleibt dadurch erhalten. Das ist der eigentliche Fix - alles andere ist Ausgestaltung. + +**Copy des Modals:** + +> ### Dein vierter Code ist fertig. Er braucht nur noch einen Platz. +> +> Du nutzt alle 3 dynamischen Codes deines kostenlosen Plans. Dieser hier ist gebaut und wartet - du kannst ihn behalten oder einen bestehenden freigeben. +> +> **[ Diesen Code mit Pro speichern - 9 € / Monat ]** +> [ Einen bestehenden Code pausieren ] +> [ Stattdessen als statischen Code herunterladen ] +> +> *Deine 3 aktiven Codes laufen weiter, egal wie du dich entscheidest.* + +Die Zahlen (`vierter`, `3`) kommen aus `limitInfo`, damit das Modal auch für Pro bei 51 stimmt. + +**Warum diese drei Optionen:** + +Der Hauptbutton verkauft keinen Plan, sondern rettet einen konkreten Code, den der Nutzer gerade in der Hand hat. Option 2 ist die ehrliche Alternative innerhalb des Free-Plans - sie kostet ein paar Conversions und kauft dafür Belief 5 aus dem Necessary-Beliefs-Doc. Option 3 ist der Ausweg ohne Verlust: ein statischer Code löst das Problem zu einem guten Teil, kostet nichts, und die Zusage „läuft nie ab" ist verifiziert. Der Schlusssatz ist Risk Reversal genau an der Stelle, an der die Kategorie ihren schlechtesten Ruf hat. + +### 1.3 Direkt-Checkout aus dem Modal + +Der Pro-Button ruft `/api/stripe/checkout` direkt auf, mit `priceId`, `plan: 'PRO'` und `userEmail`. + +**Datei:** `src/app/(main)/api/stripe/checkout/route.ts`, Zeile 63. Die `success_url` ist aktuell fest auf `/dashboard?success=true`. Sie muss eine optionale `returnPath` aus dem Request-Body akzeptieren, damit der Nutzer nach dem Kauf dorthin zurückkommt, wo er war. + +Vor dem Öffnen von Stripe wird der Formularzustand nach `localStorage` geschrieben (`qrm_pending_qr`, mit Zeitstempel). Beim Zurückkommen auf `/create?restored=1` liest die Seite ihn aus, füllt das Formular und zeigt: *„Willkommen zurück. Dein Code steht noch genau so da - jetzt mit Platz."* Danach den Key löschen. Einträge älter als 24 Stunden werden verworfen. + +Kein Draft in der Datenbank. Der Zustand ist ohnehin nur im Browser relevant, und eine Draft-Tabelle wäre Infrastruktur für ein Problem, das `localStorage` löst. + +### 1.4 Option „Code pausieren" im Modal + +Zeigt die aktiven dynamischen Codes des Nutzers mit Titel und Scan-Zahl der letzten 30 Tage. Ein Klick setzt `status = PAUSED` über das bestehende `PATCH /api/qrs/[id]`, danach wird der ursprüngliche POST automatisch wiederholt. + +Die Scan-Zahl daneben ist wichtig: sie macht die Entscheidung informiert statt willkürlich. Wer sieht, dass ein Code seit vier Wochen null Scans hat, pausiert ihn ohne schlechtes Gefühl - und wer sieht, dass alle drei laufen, versteht ohne Verkaufstext, warum Pro sinnvoll ist. Das ist Pointing statt Talking. + +--- + +## Phase 2 - `/bulk-creation` + +**Datei:** `src/app/(main)/(app)/bulk-creation/page.tsx`, Zeile 232-247 + +Die Schleife hat kein `else` zu `if (res.ok)`. Fehlgeschlagene Zeilen verschwinden still, und danach meldet ein grüner Toast `${results.length} dynamische QR-Codes erstellt!` - eine Zahl, die kleiner sein kann als das Hochgeladene, ohne jeden Hinweis. + +**Fix:** + +```ts +const failed: { row: number; title: string; reason: string }[] = []; +// im else-Zweig: failed.push({ row: i + 1, title, reason: (await res.json()).error }) +``` + +Danach, wenn `failed.length > 0`, statt des Erfolgs-Toasts ein Ergebnis-Panel: + +> **180 von 200 Codes erstellt.** +> 20 Zeilen konnten nicht angelegt werden, weil dein Kontingent an dynamischen Codes erschöpft ist. Hier sind sie - du kannst sie als statische Codes erzeugen oder dein Kontingent erhöhen. +> +> [ Fehlende Zeilen als CSV ] [ Kontingent erhöhen ] + +Zusätzlich in derselben Datei: + +- `remainingDynamic` nach dem Lauf vom Server neu laden statt nur lokal herunterzuzählen (Zeile 251). Das ist die Ursache der Race Condition. +- Die Toasts sind auf Deutsch (`'Du hast keine dynamischen QR-Codes mehr übrig...'`, Zeile 215 und 221), während die restliche App-Oberfläche Englisch ist. Auf Englisch umstellen. + +--- + +## Phase 3 - Upgrade-Wege aus der App + +`/pricing` liegt in der `(marketing)`-Route-Group. Wer im Dashboard auf Upgrade klickt, verliert die Sidebar und landet in der Marketing-Site. Zusätzlich liest `PricingClient.tsx` `searchParams` überhaupt nicht - das `?reason=limit_reached`, das `/create` heute anhängt, wird vollständig ignoriert. + +Nach der getroffenen Entscheidung läuft der Limit-Fall künftig über das Modal, damit ist der wichtigste Fall gelöst. Es bleiben drei In-App-Links auf `/pricing`: + +| Datei | Zeile | Kontext | +|---|---|---| +| `dashboard/page.tsx` | 340 | Upgrade-Badge im Header | +| `create/page.tsx` | 977 | Hinweis „Upgrade to PRO to customize colors" | +| `create/page.tsx` | 1106 | Hinweis „Upgrade to PRO to add logos" | + +Die beiden Hinweise in `/create` sollten dasselbe Modal öffnen wie der Limit-Fall, nur mit anderem Aufhänger („Dein Logo gehört in diesen Code"). Der Nutzer ist mitten im Gestalten - ihn dafür aus der Seite zu werfen ist derselbe Fehler wie beim Limit, nur weniger sichtbar. + +Der Dashboard-Badge kann auf `/pricing` zeigen bleiben. Dort ist der Nutzer nicht mitten in einer Aufgabe, es gibt nichts zu verlieren. Nur ein `?from=dashboard` anhängen und in `PricingClient` einen Zurück-Link rendern, damit der Weg zurück nicht über den Browser-Button läuft. + +--- + +## Phase 4 - Post-Download-Popup auf den Tool-Seiten + +**Datei:** `src/components/marketing/PostDownloadPopup.tsx` + +Timing und die Ablehn-Option `No thanks, keep it static` bleiben unverändert - beides ist richtig gebaut. + +Ersetzt werden Headline und Bullet-Liste: + +> ### Dieser Code zeigt jetzt für immer auf diese URL. +> +> Bei einem dauerhaften Link ist das genau richtig. Falls sich das Ziel je ändert, brauchst du einen neuen Code und neues Druckmaterial. +> +> Ein kostenloses Konto gibt dir 3 dynamische Codes: gleiches Bild, Ziel jederzeit änderbar, jeder Scan gezählt. +> +> **[ Kostenloses Konto anlegen - keine Karte ]** +> *Nein danke, statisch reicht* + +Die vier Bullets entfallen. Drei gleichrangige Vorteile sind schwächer als ein Satz, der den einen benennt - in einer Liste aus vier gleich formatierten Punkten ist keiner davon wichtig. + +Neues Prop `variant`, das nur die erste Zeile austauscht: + +| Tool | Erste Zeile | +|---|---| +| Google Review | Dieser Code zeigt jetzt für immer auf dieses Google-Profil. | +| WiFi | Dieser Code enthält jetzt dauerhaft dieses WLAN-Passwort. | +| vCard | Dieser Code enthält jetzt dauerhaft diese Kontaktdaten. | +| Crypto | Dieser Code enthält jetzt dauerhaft diese Wallet-Adresse. | +| Standard | Dieser Code zeigt jetzt für immer auf diese URL. | + +Die WiFi-Variante ist die stärkste, weil sie einen Umstand benennt, den fast niemand vorher bedenkt: Wer das Passwort ändert, hat wertloses Druckmaterial. + +Betroffen sind die 10+ Generator-Komponenten, die `PostDownloadPopup` einbinden - dort jeweils nur das `variant`-Prop ergänzen. + +**Zusätzlich:** `shouldShowDownloadPopup()` prüft einen einzigen `localStorage`-Key. Wer das Popup einmal gesehen hat, sieht es auf keiner anderen Tool-Seite je wieder - auch nicht Monate später in einem anderen Kontext. Vorschlag: Key mit Zeitstempel, Wiedervorlage nach 30 Tagen. + +--- + +## Phase 5 - Retention-Mails + +**Datei:** `src/lib/email.ts` und `src/app/(main)/api/cron/retention-emails/route.ts` + +### 5.1 Tag-7-Mail: Trigger vom Kalender aufs Verhalten + +Aktuell feuert sie bei `createdAt < 7 Tage` und `qrCount > 0`. Ein Nutzer mit einem einzigen Code bekommt „You're 2 away from the free limit" - eine Verkaufsmail über ein Limit, das ihn nicht drückt, abgeschickt unter deinem Namen. + +Neue Logik: + +| Zustand | Auslöser | Mail | +|---|---|---| +| aktive dynamische Codes = Limit | sobald erreicht | Limit-Mail, Marker `limitReachedNudgeSentAt` | +| 1-2 von 3 belegt, Tag 7 | Tag 7 | keine Upgrade-Mail | +| erster Scan liegt vor | 1 Tag danach | Erster-Scan-Mail, Marker `firstScanNudgeSentAt` | + +In der Vergleichstabelle der Limit-Mail entfällt die Zeile `CSV export: Free ✓ / Pro ✓`. Eine Zeile, in der beide Spalten identisch sind, gehört nicht in eine Upgrade-Tabelle - sie verwässert die drei, die einen Unterschied zeigen. + +### 5.2 Neue Mail: erster Scan + +`User.firstScanAt` existiert bereits und wird in `src/app/(main)/r/[slug]/route.ts` (Zeile 150-153 und 263-266) gesetzt. Es fehlt nur ein Versand-Marker. + +Betreff: **Dein Code wurde gerade zum ersten Mal gescannt** + +> Um {Uhrzeit}, auf einem {Gerät}, aus {Land}. Dein Code „{Titel}" ist im Einsatz. +> +> Ab jetzt zählt jeder weitere Scan mit. In ein paar Tagen siehst du, wann die meisten kommen - und ob sich der Ort lohnt, an dem du den Code platziert hast. +> +> [ Scans ansehen ] + +Kein Verkaufsargument. Diese Mail hat einen Anlass, der nicht konstruiert ist, und ist der Moment, in dem die Positionierung zum ersten Mal einlöst. Sie ist die einzige in der Sequenz, deren Anlass nicht vom Kalender kommt. + +### 5.3 Tag-30-Mail auf Scan-Daten umbauen + +Zwei Probleme mit der jetzigen Fassung: + +Der Satz *„The one thing I hear most from Pro users who switched after a few weeks: they wish they'd added their brand sooner"* behauptet ein Muster aus Kundengesprächen. Wenn es die gab: echtes Zitat rein. Wenn nicht: **streichen** - das ist ein erfundenes Testimonial in indirekter Rede und verstößt gegen die Beweisregel im Product Context. Bei einer Zielgruppe, die Bewertungsportale liest, ist das die teuerste Art von Satz. + +Und Branding ist der schwächere von zwei verfügbaren Aufhängern. Nach 30 Tagen hat der Nutzer Scan-Daten. Neuer Aufbau: + +> Deine Codes wurden diesen Monat {n}-mal gescannt, {Vorname}. +> +> Die meisten davon {Wochentag}s. Was du noch nicht sehen kannst: von welchen Geräten sie kamen und aus welchen Orten - und damit, welche deiner Platzierungen die Scans wirklich gebracht hat. +> +> [ Vollständige Auswertung freischalten ] + +Damit ist der Kaufgrund aus dem hergeleitet, was der Nutzer selbst erlebt hat. Deckt sich mit Offer Brief §10, Option 1 - auf Analytics-Tiefe metern statt auf Code-Anzahl -, und ist die erste Stelle, an der man das testen kann, ohne das Pricing anzufassen. + +### 5.4 Tag-3-Mail: kleine Korrektur + +Betreff `You haven't made one yet` kann als Vorwurf gelesen werden - im Body löst die Headline es auf, im Posteingang steht der Betreff allein. Alternative gleicher Länge: **`Your 3 free codes are still sitting there`**. + +--- + +## Phase 6 - QR-Design nach Plan gestaffelt + +Neue Staffelung: Farben ab Free, Formen ab Pro, alles ab Business. + +### 6.0 Der technische Blocker, der vorher geklärt sein muss + +`/create` rendert über `QRCodeSVG` aus `qrcode.react` (Zeile 6 und 1233). **Diese Bibliothek kann ausschließlich quadratische Module.** Es gibt heute überhaupt keine Formauswahl im Produkt - nicht weil sie gesperrt wäre, sondern weil der Renderer sie nicht kann. + +Für Formen muss der Renderer also getauscht werden. Es gibt zwei Kandidaten, und sie decken unterschiedlich viel ab: + +| Renderer | Kann | Kann nicht | +|---|---|---| +| `qr-code-styling` (liegt bereits als Dependency in `package.json`, Zeile 64, ungenutzt) | square, dots, rounded, extra-rounded, classy, classy-rounded, Eye-Styles getrennt, Verläufe, Logo | star, plus, hexagon, diamond, mosaic, liquid | +| Canvas-Renderer aus `qr-design-showcase.html` | alle 11 Formen inklusive star, plus, hexagon, diamond, mosaic, liquid, Rahmen mit Label, Logo-Formen | ist eigener Code, muss portiert und gepflegt werden | + +Das trifft sich gut mit der gewünschten Staffelung: **Pro läuft komplett über `qr-code-styling`** - vier Formen, geringer Aufwand, Bibliothek ist schon da. **Business braucht den portierten Showcase-Renderer** für die exotischen Formen. Damit ist der Mehraufwand genau dort, wo auch der höhere Preis ist. + +### 6.1 Free - Farben + +**Datei:** `src/app/(main)/(app)/create/page.tsx`, Zeile 167 + +```ts +const canCustomizeColors = true; // war: PRO || BUSINESS +const canUseShapes = userPlan === 'PRO' || userPlan === 'BUSINESS'; +const canUseFullDesign = userPlan === 'BUSINESS'; +const canUseLogo = userPlan === 'PRO' || userPlan === 'BUSINESS'; +``` + +Damit fallen die beiden Zwangsüberschreibungen in Zeile 408-409 weg, die heute für Free-Nutzer stumpf `#000000` und `#FFFFFF` einsetzen. Der Upgrade-Hinweis-Block ab Zeile 972 („Upgrade to PRO to customize colors, add logos, and brand your QR codes") entfällt komplett - er stimmt danach nicht mehr. + +Der Logo-Block ab Zeile 1104 bleibt, wird aber auf `canUseLogo` umgestellt statt auf `canCustomizeColors`, und öffnet künftig das Modal aus Phase 3 statt auf `/pricing` zu verlinken. + +**Der Kontrast-Check bleibt aktiv.** `calculateContrast` gibt es bereits (Zeile 221). Sobald Farben für alle offen sind, wird er wichtiger, nicht unwichtiger - Free-Nutzer sind die Gruppe mit der geringsten Erfahrung darin, was noch scannbar ist. Bei zu geringem Kontrast eine Warnung, kein Verbot: *„Dieser Kontrast ist grenzwertig. Auf gedrucktem Material scannen helle Codes auf hellem Grund oft nicht."* + +### 6.2 Pro - vier Modulformen + +Umsetzung über `qr-code-styling`. Bewusst nur vier, nicht sechs: + +| Auswahl | `dotsOptions.type` | Wofür | +|---|---|---| +| Eckig (klassisch) | `square` | Standard, höchste Scan-Sicherheit | +| Abgerundet | `rounded` | weicher, ohne Lesbarkeit zu kosten | +| Punkte | `dots` | modern, deutlich sichtbarer Unterschied | +| Fließend | `classy-rounded` | markantester der vier | + +Dazu die Eye-Styles (`cornersSquareOptions`, `cornersDotOptions`) - eckig, abgerundet, Kreis. Die Augen machen optisch mehr aus als die Module selbst und kosten nichts extra, weil dieselbe Bibliothek sie mitbringt. + +Vier Optionen statt aller sechs, weil die Auswahl selbst ein Verkaufsargument ist: Pro fühlt sich vollständig an, Business hat sichtbar mehr. Sechs fast identische Varianten wirken dagegen wie eine lange Liste ohne Unterschied. + +### 6.3 Business - vollständiger Designer + +Portierung des Renderers aus `qr-design-showcase.html` in eine Komponente `src/components/generator/AdvancedQRRenderer.tsx`. Was damit dazukommt: + +- **Modulformen:** diamond, star, hexagon, plus, mosaic, liquid zusätzlich zu den vier aus Pro +- **Eye-Frames getrennt:** eckig, abgerundet, Kreis, Blatt, Flower/Squircle, Hexagon +- **Eye-Balls getrennt:** eckig, abgerundet, Kreis, Diamant, Stern, Hexagon +- **Farbverläufe:** linear und radial statt einfarbig +- **Rahmen mit Label:** weiße Karte mit Schatten, Label oben oder unten (z. B. „Speisekarte", „Jetzt bewerten") +- **Logo-Formen:** Punkt, Quadrat, Herz, Blitz, WLAN-Symbol +- **Fehlerkorrektur-Stufe** frei wählbar (L/M/Q/H) + +**Erweiterungsvorschläge über die Showcase hinaus**, weil beim Business-Kunden die Wiederholbarkeit zählt und nicht die einzelne Spielerei: + +1. **Design-Vorlagen speichern.** Ein einmal gebautes Design als benanntes Preset sichern und auf neue Codes anwenden. Das ist für eine Agentur mit mehreren Kunden der eigentliche Wert - nicht die Sternform, sondern dass Kunde A immer gleich aussieht. +2. **Preset auf den Bulk-Flow anwenden.** Ein Preset auswählen und alle 500 Codes eines Uploads tragen es. Das verbindet Phase 2 mit diesem Feature und ist das erste Argument für Business, das nicht nur eine Zahl ist. +3. **Print-Vorschau in Originalgröße.** Der Code in 2×2 cm, 4×4 cm und 10×10 cm dargestellt, mit Hinweis ab wann es kritisch wird. Passt zu den Druckangaben, die im Offer Brief bereits als verifizierter Fakt geführt werden. + +### 6.4 Scanbarkeit - der Teil, der nicht optional ist + +Exotische Formen füllen weniger Fläche pro Modul. Star, plus und mosaic reduzieren die Kontrastfläche spürbar, und in Kombination mit einem Logo in der Mitte und einer kleinen Druckgröße kippt die Lesbarkeit. Die Showcase weist bei „H (30%)" schon auf „empfohlen bei Logo" hin - das gehört ins Produkt übernommen, und zwar strenger: + +- Bei star, plus, mosaic oder liquid automatisch auf Fehlerkorrektur **H** hochsetzen und das sichtbar begründen +- Bei Logo plus exotischer Form eine Warnung mit Mindestdruckgröße +- Ein **Test-Scan-Hinweis** vor dem Download: *„Scanne den Code einmal mit deinem eigenen Handy, bevor du ihn in Druck gibst."* + +Das ist kein Beiwerk, sondern der Proof-Layer aus der Positionierung an einer Stelle, an der es konkret wird. Ein Anbieter, der vor seinem eigenen Feature warnt, wenn es kritisch wird, belegt Belief 5 besser als jede Aussage über Transparenz. + +### 6.5 Was die Umstellung beim Pricing kostet + +Ehrlich gesagt: Farben waren laut Offer Brief §10 einer von genau **drei** Gründen, heute auf Pro zu wechseln (die anderen zwei: mehr als 3 aktive Codes, Device- und Location-Breakdown). Diesen Grund gibt man mit dieser Änderung auf. + +Das ist meiner Einschätzung nach trotzdem richtig, aber aus einem anderen Grund als „großzügiger sein": + +Farben sind kein guter Upgrade-Anlass, weil man sie schon im kostenlosen Zustand *sehen* will, um zu verstehen, ob das Produkt etwas taugt. Ein Free-Nutzer, der nur schwarze Codes bauen kann, hält das Produkt für ein Basiswerkzeug - und bewertet es entsprechend, auch in Vergleichen. Formen sind der bessere Verkäufer, weil der Unterschied größer aussieht und man ihn in der Vorschau zeigen kann, bevor man ihn freischaltet: der Nutzer wählt „Punkte", sieht das Ergebnis live, und erst der Download fragt nach Pro. + +**Folgeänderungen an der Preis-Copy** in `src/i18n/en.json` und `src/app/(main)/(marketing)/pricing/PricingClient.tsx`: + +| Plan | vorher | nachher | +|---|---|---| +| Free | „Standard QR design templates" | „Deine Farben - Vorder- und Hintergrund frei wählbar" | +| Pro | „Custom branding (colors & logos)" | „4 Modulformen, eigene Eye-Styles und dein Logo im Code" | +| Business | (kein Design-Punkt) | „Voller Designer: 10 Formen, Verläufe, Rahmen mit Label, speicherbare Design-Vorlagen" | + +Dieselbe Anpassung auf `/custom-qr-code-generator`, dessen Meta-Description aktuell „Put your logo and brand colors into the code itself" sagt - das bleibt korrekt, weil Logo weiterhin Pro ist, aber die Seite sollte künftig zeigen, was auf welcher Stufe geht. + +### 6.6 Keine Datenbankänderung nötig + +`QRCode.style` ist bereits `Json` (siehe `prisma/schema.prisma`). Alle neuen Felder - `dotType`, `eyeFrameType`, `eyeBallType`, `gradient`, `frameLabel`, `logoShape`, `ecLevel` - passen ohne Schemaänderung hinein. Bestehende Codes haben die Felder schlicht nicht und fallen auf die Defaults zurück. + +**Ausnahme:** Wenn die speicherbaren Design-Vorlagen aus 6.3 kommen sollen, braucht es eine eigene Tabelle. SQL dafür steht unten, ist aber optional und kann später nachgezogen werden. + +--- + +## SQL - alle nötigen Datenbankänderungen + +Nach der Policy in `CLAUDE.md`: keine Prisma-Migrationen, nur direkte Statements. + +```sql +-- Marker für die neuen verhaltensbasierten Retention-Mails +ALTER TABLE "User" ADD COLUMN IF NOT EXISTS "limitReachedNudgeSentAt" TIMESTAMP(3); +ALTER TABLE "User" ADD COLUMN IF NOT EXISTS "firstScanNudgeSentAt" TIMESTAMP(3); + +-- Index für den Cron: sucht Nutzer mit erstem Scan, die die Mail noch nicht haben +CREATE INDEX IF NOT EXISTS "User_firstScanAt_firstScanNudgeSentAt_idx" + ON "User" ("firstScanAt", "firstScanNudgeSentAt"); + +-- Index für die neue Limit-Query (zählt nur noch ACTIVE) +CREATE INDEX IF NOT EXISTS "QRCode_userId_type_status_idx" + ON "QRCode" ("userId", "type", "status"); +``` + +Für Phase 6 ist **nichts** davon nötig - `QRCode.style` ist bereits `Json`. Optional, nur falls die speicherbaren Design-Vorlagen aus 6.3 gebaut werden: + +```sql +CREATE TABLE IF NOT EXISTS "QRDesignPreset" ( + "id" TEXT PRIMARY KEY, + "userId" TEXT NOT NULL REFERENCES "User"("id") ON DELETE CASCADE, + "name" TEXT NOT NULL, + "style" JSONB NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT now(), + "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT now() +); + +CREATE INDEX IF NOT EXISTS "QRDesignPreset_userId_idx" ON "QRDesignPreset" ("userId"); +CREATE UNIQUE INDEX IF NOT EXISTS "QRDesignPreset_userId_name_key" ON "QRDesignPreset" ("userId", "name"); +``` + +Ausführen über `npm run docker:db` oder: + +```bash +docker-compose exec db psql -U postgres -d qrmaster -c 'ALTER TABLE "User" ADD COLUMN IF NOT EXISTS "limitReachedNudgeSentAt" TIMESTAMP(3);' +``` + +Danach `prisma/schema.prisma` im Block `// Retention email tracking` ergänzen: + +```prisma + limitReachedNudgeSentAt DateTime? + firstScanNudgeSentAt DateTime? +``` + +und beim Model `QRCode` den Index: + +```prisma + @@index([userId, type, status]) +``` + +Abschließend `npx prisma generate` - kein `migrate`. + +### Prüf-Queries vor dem Deploy + +```sql +-- Wie viele Free-Nutzer bekommen durch die ACTIVE-Umstellung Slots frei? +SELECT COUNT(DISTINCT u.id) +FROM "User" u +JOIN "QRCode" q ON q."userId" = u.id +WHERE u.plan = 'FREE' AND q.type = 'DYNAMIC' AND q.status = 'PAUSED'; + +-- Wie viele Nutzer bekämen die Erster-Scan-Mail beim ersten Cron-Lauf? +SELECT COUNT(*) FROM "User" +WHERE "firstScanAt" IS NOT NULL AND "firstScanNudgeSentAt" IS NULL; +``` + +Die zweite Zahl ist wichtig: Beim ersten Lauf würde die neue Mail an **alle** Bestandsnutzer mit Scan-Historie gehen - auch an solche, deren erster Scan Monate zurückliegt. Das wäre kein Anlass mehr, sondern Spam. Der Cron braucht deshalb ein Zeitfenster, etwa `firstScanAt > now() - interval '7 days'`, oder man setzt die Spalte bei Bestandsnutzern einmalig vor: + +```sql +UPDATE "User" SET "firstScanNudgeSentAt" = now() +WHERE "firstScanAt" IS NOT NULL AND "firstScanAt" < now() - interval '7 days'; +``` + +--- + +## Reihenfolge + +| # | Was | Aufwand | DB | +|---|---|---|---| +| 1 | Limit-Query auf ACTIVE, beide Endpoints | klein | Index | +| 2 | Limit-Modal ohne Redirect | mittel | nein | +| 3 | Direkt-Checkout plus `returnPath` und localStorage-Wiederherstellung | mittel | nein | +| 4 | `bulk-creation`: Fehlerbehandlung und Ergebnis-Panel | klein | nein | +| 5 | Popup-Copy plus `variant` pro Tool-Seite | klein | nein | +| 6 | Retention: Trigger umstellen, Tabellen-Zeile raus, Betreff Tag 3 | klein | 1 Spalte | +| 7 | Erster-Scan-Mail | mittel | 1 Spalte | +| 8 | Tag-30 auf Scan-Daten, unbelegten Satz klären | klein | nein | +| 9 | Farben ab Free freischalten, Pricing-Copy nachziehen | klein | nein | +| 10 | Pro-Formen über `qr-code-styling`, Renderer-Tausch in `/create` | mittel | nein | +| 11 | Business-Designer, Showcase-Renderer portieren | groß | nein | +| 12 | Design-Vorlagen speichern und auf Bulk anwenden | mittel | Tabelle | + +1 bis 3 gehören zusammen und sollten gemeinsam live gehen. 4 und 5 sind unabhängig und können jederzeit dazwischen. 6 bis 8 brauchen die SQL-Statements und den einmaligen `UPDATE` für Bestandsnutzer. + +**9 ist der schnellste Gewinn im ganzen Dokument** - eine Zeile (`canCustomizeColors = true`) plus Copy-Anpassung, und das Produkt wirkt für jeden neuen Nutzer sofort weniger nach Basiswerkzeug. Sie sollte nicht auf 10 warten. + +10 ist der Renderer-Tausch und damit der Punkt, an dem `/create` einmal gründlich getestet werden muss - Vorschau, Download PNG, Download SVG, Logo-Overlay und die Frame-Optionen hängen alle daran. + +11 und 12 sind der eigentliche Business-Ausbau. 12 ist dabei wertvoller als 11: eine Agentur kauft nicht die Sternform, sondern dass Kunde A auf 500 Codes gleich aussieht. diff --git a/RETENTION_UND_CRO_ANALYSE_2026-07-27.md b/RETENTION_UND_CRO_ANALYSE_2026-07-27.md new file mode 100644 index 0000000..6952fc8 --- /dev/null +++ b/RETENTION_UND_CRO_ANALYSE_2026-07-27.md @@ -0,0 +1,169 @@ +# Retention-Mails & CRO-Momente - Analyse + +Stand 27. Juli 2026. Grundlage: `src/lib/email.ts`, `src/app/(main)/api/cron/retention-emails/route.ts`, `src/components/marketing/PostDownloadPopup.tsx`, `src/app/(main)/(app)/create/page.tsx` sowie Offer Brief §10 und der Necessary-Beliefs-Doc. + +--- + +## Teil 1 - Der 3/3-Moment: es gibt kein Popup + +Das Wichtigste zuerst, weil es kein Copy-Problem ist. + +Wenn ein Free-Nutzer den vierten dynamischen Code anlegen will, passiert laut `create/page.tsx` Zeile 456-458 Folgendes: + +``` +if (response.status === 403 && responseData.error === 'Limit reached') { + showToast(responseData.message || 'You have reached your plan limit.', 'error'); + router.push('/pricing?reason=limit_reached'); +} +``` + +Drei Dinge gehen hier schief, in aufsteigender Schwere: + +**1. Roter Fehler-Toast.** Der Nutzer hat nichts falsch gemacht. Er hat das Produkt so benutzt, wie es gedacht ist, und bekommt dafür eine Fehlermeldung im gleichen Stil wie eine kaputte URL. Das ist keine Upgrade-Aufforderung, das ist eine Zurechtweisung. + +**2. Die Arbeit ist weg.** Der Nutzer hat Ziel-URL, Typ, Farben, vielleicht ein Logo eingegeben. Beim Redirect auf `/pricing` ist all das verloren. Wer danach upgradet, muss von vorne anfangen. Das ist der teuerste denkbare Zeitpunkt für Datenverlust: exakt in dem Moment, in dem die Kaufabsicht am höchsten ist. + +**3. Der Redirect ist ein Rauswurf.** Der Nutzer wollte einen QR-Code bauen und landet auf einer Preistabelle ohne Bezug zu dem, was er gerade tat. Kein Weg zurück, kein „so sieht dein Code aus, er ist nur noch nicht gespeichert". + +Aus dem Offer Brief §7: der Engpass ist **Perceived Likelihood**, nicht Preis und nicht Effort. Dieser Ablauf senkt genau die - er zeigt, dass das Produkt in einem kritischen Moment die eigene Arbeit wegwirft. + +### Was stattdessen hin muss + +Ein Modal, das **über** dem fertigen Code aufgeht, nicht statt ihm. Der Code bleibt im Hintergrund sichtbar. Vorschlag: + +> **Dein vierter Code ist fertig. Er braucht nur noch einen Platz.** +> +> Du nutzt alle 3 dynamischen Codes des Free-Plans. Dieser hier ist gebaut und wartet - du kannst ihn behalten oder einen bestehenden freigeben. +> +> [ Diesen Code mit Pro speichern - 9 € / Monat ] +> [ Einen bestehenden Code ersetzen ] +> [ Stattdessen als statischen Code herunterladen - kostenlos, läuft nie ab ] +> +> Deine 3 aktiven Codes laufen weiter, egal wie du dich entscheidest. + +Warum diese drei Optionen: + +- **Option 1** ist der Kauf, aber formuliert als „diesen konkreten Code retten", nicht als „Plan kaufen". Der Nutzer kauft eine Sache, die er gerade in der Hand hat. +- **Option 2** ist die ehrliche Alternative innerhalb des Free-Plans. Sie kostet ein paar Conversions und kauft dafür Glaubwürdigkeit - Belief 5 aus dem Necessary-Beliefs-Doc: der sicherste Anbieter ist der, der offenlegt, was er kann und was nicht. +- **Option 3** ist der Ausweg ohne Verlust. Ein statischer Code löst das Problem des Nutzers zu 60 % und kostet nichts, und die Zusage „läuft nie ab" ist verifiziert. Wer sie nimmt, ist nicht verloren - er hat gerade erlebt, dass das Produkt ihm nichts wegnimmt. + +Der letzte Satz ist Risk Reversal an genau der Stelle, wo die Kategorie ihren schlechtesten Ruf hat: das Abschalten bereits gedruckter Codes. + +--- + +## Teil 2 - Die Retention-Mails + +Die Copy ist besser als der Durchschnitt. Absenderpersona ist da (Timo, Founder, Reply geht an einen Menschen), keine Ausrufezeichen-Orgie, konkrete Zahlen. Was fehlt, liegt eine Ebene tiefer. + +### Mail 1 - Tag 3, Aktivierung + +Betreff: `You haven't made one yet` +Headline: `You haven't made one yet, {Name}. 3 days since signup · 0 QR codes created` + +Das ist die stärkste der drei. Der Betreff ist ein Pattern Interrupt in einem Posteingang voller „Tips & Tricks", und die Zeile `Your 3 free dynamic QR codes are still there. Unused.` ist Pointing statt Talking. + +Zwei Schwächen: + +**Der Betreff kann als Vorwurf gelesen werden.** „You haven't made one yet" mit Doppeldeutigkeit - ist das eine Beobachtung oder eine Rüge? Die Headline im Body löst es auf, der Betreff allein nicht. Alternative, gleiche Länge, ohne Vorwurfsrisiko: `Your 3 free codes are still sitting there`. + +**Es fehlt der Anlass.** Die Mail erklärt, *wie* man einen Code macht (drei Schritte), aber nicht, *wofür der Empfänger sich damals angemeldet hat*. Wenn beim Signup die Quelle bekannt ist - kam er über `/tools/google-review-qr-code`, über die Restaurant-Seite, über Bulk? -, dann gehört Schritt 01 personalisiert. „Paste your URL" ist die generischste denkbare Aufforderung an jemanden, der wegen Google-Reviews kam. + +### Mail 2 - Tag 7, Upgrade + +Betreff: `You're at the free limit` bzw. `You're 2 away from the free limit` +Headline: `{n} of 3 free codes used, {Name}.` + +Hier ist der Trigger das Problem, nicht die Worte. + +**Die Mail feuert am Tag 7, unabhängig vom Verhalten.** Die Bedingung im Cron ist `createdAt < 7 Tage` und `qrCount > 0` und `plan = FREE`. Ein Nutzer mit **einem** Code bekommt eine Mail mit dem Betreff „You're 2 away from the free limit" - über ein Limit, das ihn nicht drückt und vielleicht nie drücken wird. Das ist eine Upgrade-Aufforderung an jemanden ohne Schmerz. Solche Mails trainieren Empfänger darauf, den Absender zu ignorieren, und der Absender ist hier der Gründer persönlich - das ist teurer Kredit, den man nicht für eine Fehlzündung ausgeben sollte. + +**Empfehlung: den Trigger vom Kalender aufs Verhalten umstellen.** + +| Zustand | Auslöser | Inhalt | +|---|---|---| +| 3 von 3 belegt | sobald erreicht, nicht Tag 7 | Limit-Mail wie jetzt, aber sofort im Moment der Relevanz | +| 1-2 von 3 belegt | Tag 7 | keine Upgrade-Mail. Stattdessen: was die Scan-Daten des ersten Codes zeigen | +| 3 von 3 und erster Code hat Scans | 3 Tage nach Limit | Upgrade mit den eigenen Zahlen des Nutzers als Beweis | + +Das dritte Szenario ist die eigentlich fehlende Mail. Nichts überzeugt einen Marketing-Manager so wie sein eigener erster Datenpunkt: „Dein Code auf dem Flyer hatte 47 Scans, die meisten dienstags zwischen 11 und 14 Uhr." Das ist Pointing in Reinform, und es kostet nichts außer der Query. + +**Und ein inhaltlicher Fehler.** Die Vergleichstabelle listet `CSV export: Free ✓ / Pro ✓`. Eine Zeile, in der beide Spalten identisch sind, ist in einer Upgrade-Tabelle wertlos - sie füllt Platz und verwässert die drei Zeilen, die tatsächlich einen Unterschied zeigen. Streichen. + +### Mail 3 - Tag 30 + +Betreff: `{Name}, a month of QR codes - one upgrade worth making` +Argument: Pro-Nutzer bereuen, das Branding nicht früher hinzugefügt zu haben. + +**Das Argument ist gut gebaut und nicht belegt.** Der Satz `The one thing I hear most from Pro users who switched after a few weeks: they wish they'd added their brand sooner` behauptet ein Muster aus Kundengesprächen. Wenn diese Gespräche stattgefunden haben: rein damit, am besten mit einem echten Zitat. Wenn nicht, ist das ein erfundenes Testimonial in indirekter Rede und verstößt gegen die Beweisregel aus dem Product Context („keine erfundenen Testimonials"). Bei einer Zielgruppe, die Bewertungsportale liest, ist das die teuerste Art von Satz. + +**Der Aufhänger ist außerdem der schwächere von zwei verfügbaren.** Branding ist ein Ästhetik-Argument. Nach 30 Tagen mit mehreren Codes hat der Nutzer etwas viel Stärkeres in der Hand: Scan-Daten. Der Tag-30-Anlass sollte der erste echte Report sein, nicht ein Logo-Feature. „Deine Codes wurden diesen Monat X-mal gescannt. Hier ist, was du noch nicht sehen kannst" - und dann Device- und Location-Breakdown als das, was Pro freischaltet. Das ist derselbe Kaufgrund, aber hergeleitet aus dem, was der Nutzer selbst erlebt hat. + +Das deckt sich mit Offer Brief §10, Option 1: auf Analytics-Tiefe metern statt auf Code-Anzahl. Diese Mail wäre die erste Stelle, an der man das testen kann, ohne das Pricing anzufassen. + +### Übergreifend: es fehlt die Mail nach dem ersten Scan + +Die Sequenz ist Tag 3, Tag 7, Tag 30 - drei Kalendertermine. Der wichtigste Moment im Lebenszyklus dieses Produkts kommt in keinem davon vor: **der erste Scan eines Codes.** Das ist der Augenblick, in dem aus einem Tool eine Messung wird und in dem das Versprechen der Positionierung zum ersten Mal einlöst. Eine Mail „Dein Code wurde gerade zum ersten Mal gescannt" hat einen Anlass, der nicht konstruiert ist, und braucht überhaupt kein Verkaufsargument. + +--- + +## Teil 3 - Das Post-Download-Popup auf den Tool-Seiten + +Aktuell: + +> **Your QR code is downloading!** +> Want to make it smarter - for free? +> +> - Edit the link anytime - QR stays the same +> - See who scans, when & where +> - Custom colors, logo & frames +> - Free plan included - upgrade anytime for more +> +> [ Create Free Account ] / *No thanks, keep it static* + +### Was funktioniert + +Das Timing ist richtig: nach dem Download, nicht davor. Der Nutzer hat bekommen, wofür er kam - das Popup nimmt ihm nichts weg. Und `No thanks, keep it static` ist eine ehrliche Ablehn-Option ohne Beschämung, was in dieser Kategorie selten ist. Nicht anfassen. + +### Was nicht funktioniert + +**Die Headline sagt nichts.** `Your QR code is downloading!` ist eine Statusmeldung. Der Nutzer sieht den Download in seinem Browser, er braucht keine Bestätigung. Diese Zeile ist die prominenteste Fläche des Popups und verbraucht sie für eine Information, die der Nutzer schon hat. + +**Der Kernnutzen ist die dritte Zeile in einer Bullet-Liste.** `Edit the link anytime - QR stays the same` ist das gesamte Argument des Produkts, versteckt zwischen einem Icon und drei gleichgewichtigen Geschwistern. In einer Liste von vier gleich formatierten Punkten ist keiner davon wichtig. + +**Es fehlt der Anlass in diesem Moment.** Der Nutzer hat gerade einen **statischen** Code heruntergeladen. Der interessante Satz ist nicht „mach ihn schlauer", sondern die Konsequenz dessen, was er gerade getan hat: dieser Code ist ab jetzt festgelegt. Das ist kein Vorwurf und keine Drohung, das ist eine Tatsache über die Datei in seinem Download-Ordner - und exakt Belief 1 aus dem Necessary-Beliefs-Doc. + +**Es ist auf allen Tool-Seiten identisch.** Wer auf `/tools/google-review-qr-code` war, will Bewertungen. Wer auf `/tools/wifi-qr-code` war, will Gäste ins WLAN. Ein Popup, das beiden dasselbe sagt, spricht keinem von beiden. + +### Vorschlag + +> **Dieser Code zeigt jetzt für immer auf diese URL.** +> +> Das ist bei einem dauerhaften Link genau richtig. Falls sich das Ziel je ändert, brauchst du einen neuen Code und neues Druckmaterial. +> +> Ein kostenloses Konto gibt dir 3 dynamische Codes: gleiches Bild, Ziel jederzeit änderbar, jeder Scan gezählt. +> +> [ Kostenloses Konto anlegen - keine Karte ] +> *Nein danke, statisch reicht* + +Struktur dahinter: P.I.G.-Opening auf eine Tatsache statt auf ein Feature, dann die Zugeständnis-Zeile („bei einem dauerhaften Link genau richtig") - das ist Offer Brief §9, die Konzession als Glaubwürdigkeits-Move -, dann erst der Mechanismus. Die Bullet-Liste entfällt komplett; drei gleichrangige Vorteile sind schwächer als ein Satz, der den einen benennt. + +Pro Tool-Seite variiert nur die erste Zeile: + +| Tool | Erste Zeile | +|---|---| +| Google Review | Dieser Code zeigt jetzt für immer auf dieses Google-Profil. | +| WiFi | Dieser Code enthält jetzt dauerhaft dieses WLAN-Passwort. | +| vCard | Dieser Code enthält jetzt dauerhaft diese Kontaktdaten. | +| URL / Standard | Dieser Code zeigt jetzt für immer auf diese URL. | + +Die WiFi-Variante ist die stärkste der vier, weil sie einen Umstand benennt, den fast niemand vorher bedenkt: das Passwort steht in der gedruckten Datei. Wer es ändert, hat wertloses Material. + +--- + +## Reihenfolge nach Wirkung pro Aufwand + +1. **Das 3/3-Modal bauen.** Momentan verliert das Produkt an der Stelle mit der höchsten Kaufabsicht die Arbeit des Nutzers. Das ist der einzige Punkt hier, der auch Entwicklungsarbeit ist und nicht nur Text. +2. **Trigger der Tag-7-Mail auf Verhalten umstellen.** Query-Änderung im Cron, keine neue Infrastruktur. +3. **Popup-Copy und Headline umstellen**, mit Variante pro Tool-Seite. +4. **Die „erster Scan"-Mail** ergänzen - der einzige Anlass in der ganzen Sequenz, der nicht vom Kalender kommt. +5. **Tag 30 auf Scan-Daten umbauen** statt Branding, und den unbelegten Pro-Nutzer-Satz entweder belegen oder streichen. diff --git a/design-variants/bakeoff.html b/design-variants/bakeoff.html new file mode 100644 index 0000000..98906f6 --- /dev/null +++ b/design-variants/bakeoff.html @@ -0,0 +1,116 @@ + + + + + +QR Master — Design Bake-off + + + + +
+
+ Design
Collection:
+
+ + + + + + +
+
+
Left = Light · Right = Dark · Keys 1–6
+
+ +
+
+
ClassicalLight
+ +
+
+
ClassicalDark
+ +
+
+ + + + diff --git a/design-variants/landing-blueprint.html b/design-variants/landing-blueprint.html new file mode 100644 index 0000000..dc40c0f --- /dev/null +++ b/design-variants/landing-blueprint.html @@ -0,0 +1,2080 @@ + + + + + +QR Master — Blueprint / Print-Tech — Design Variant + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+ BLUEPRINT 3.0 Free Dynamic QR Code Generator +

Free Dynamic QR Code Generator with Tracking

+

+ Create static and dynamic QR codes with editable destinations, scan analytics, custom branding, and bulk creation. +

+
    +
  • + No credit card required
  • +
  • + Free forever static codes
  • +
  • + Real-time scan analytics
  • +
  • + Custom colors & branding
  • +
+ +
+ Select type: + URL + vCard + WiFi + PDF + Event + Coupon + App Store + Call +
+
+ + +
+ + +
+ + + + + + +
+
+ https://www.qrmaster.net + Live Specimen +
+
+
+
+ + +
+
+
+
0/5
Customer Rating
+
0+
Verified Reviews
+
0
Free Specialized Tools
+
0
To Start Forever
+
+
+
+ + +
+
+
+
+ 01 Instant Studio +

Interactive QR Code Generator Studio

+

Type a URL or destination, pick colors, test WCAG contrast, and download SVG or PNG instantly without signup.

+
+
SVG + PNG : High-Res 300 DPI : 100% Free
+
+ +
+ +
+
+ + +
+ +
+ +
+ + + + + + +
+
+ +
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+
+ + +
+
+ + +
230px
+
+
+ +
+ Good contrast + WCAG Ratio: 16.2:1 +
+ +
+ + +
+ + Save & Track Analytics + + +
+ + +
+ Real-Time Studio Canvas +
+ + + + +
+ +
+
+
https://www.qrmaster.net
+
Scan with any smartphone camera
+
+
+
+
+ + +
+
+
+
+ 02 AI Innovation +

The future of QR codes is AI-powered

+

Next-generation intelligence for QR code generation, design optimization, and scan prediction.

+
+
In Active Development
+
+ +
+
+ A1 +

Smart QR Generation

+
    +
  • AI-powered content optimization
  • +
  • Intelligent design & color matching
  • +
  • Auto vCard creation from LinkedIn
  • +
  • SEO-optimized short URLs
  • +
+
+
+ A2 +

Predictive Analytics

+
    +
  • AI scan rate forecasting
  • +
  • Anomaly & fraud detection
  • +
  • Natural language analytics queries
  • +
  • Automated performance alerts
  • +
+
+
+ A3 +

Smart Content Hub

+
    +
  • Automated campaign tagging
  • +
  • Smart bulk CSV generation
  • +
  • AI fallback destination routing
  • +
  • Dynamic content personalization
  • +
+
+
+ A4 +

Creative Studio AI

+
    +
  • AI custom artistic QR designs
  • +
  • Auto-generated marketing copy
  • +
  • Automated A/B split testing
  • +
  • Print-ready layout checks
  • +
+
+
+ +
+
Get early access when AI features launch
+
+ + +
+

Join 1,400+ creators on the VIP access list

+
+ + You are on the list. We will notify you first! +
+
+
+
+ + +
+
+
+
+ 03 Tool Index +

18 Specialized Free QR Code Tools

+

Create dedicated QR codes for every use case. 100% free with no registration required.

+
+
18 Tools : No Account Needed
+
+ +
+ +
+ +
+
+
+ + +
+
+
+ 04 Workflows +

Popular QR Master Workflows

+

High-intent solutions for editable QR codes, spreadsheet batches, barcodes, meeting links, and local business campaigns.

+
+ +
+
+ + +
+
+
+ 05 Industry Guides +

QR Codes by Industry

+

Explore how modern teams use dynamic QR codes to track offline engagement and convert physical traffic.

+
+ + +
+
+ + +
+
+
+
+ 06 Social Proof +

Trusted by Businesses Worldwide

+

Real stories from restaurant owners, marketers, and designers using QR Master.

+
+
4.9/5 Rating : 12 Verified Reviews
+
+
+
+
+
+
+ Read All 12 Customer Stories + + +
+
+ + +
+
+
+
+ 07 Feature Comparison +

Why Dynamic QR Codes Save You Money

+

Stop re-printing physical materials every time a URL changes. Update destination links instantly and track every scan.

+
+
Static = Fixed Forever : Dynamic = Editable Forever
+
+ +
+
+
+
Static QR
Always Free
+
Dynamic QR
Recommended
+
+
+
Edit Destination URL Anytime
+
Fixed Forever
+
YES (Instant)
+
+
+
Real-Time Scan AnalyticsTime, device type, location
+
Not Available
+
YES
+
+
+
Custom Branding & Logo Overlay
+
Basic Only
+
YES
+
+
+
Bulk Creation from Excel/CSV
+
Manual Only
+
YES
+
+
+
No Account Required to CreateDynamic account signup takes under 60 seconds
+
YES
+
Free Account
+
+
+
+
+ + +
+
+
+
+ 08 Interactive ROI Calculator +

Are you burning budget on static reprints?

+

Estimate your annual print savings by switching from static printed codes to dynamic QR codes.

+ +
+ + +
+ +
+ + +
+ + Calculate Custom Campaign ROI + + +
+ +
+ Estimated Annual Savings + €1,125 + *Based on average €0.15 print cost per unit, industry estimate +
+
+
+
+ + +
+
+
+ 09 Platform Highlights +

Everything You Need for Professional QR Campaigns

+
+
+
+ F/01 +

Real-Time Scan Analytics

+

Track total scans, device breakdown, geographic locations, and time trends in an intuitive dashboard.

+
+
+ F/02 +

Full Brand Customization

+

Customize colors, corner styles, and add your company logo for seamless visual brand alignment.

+
+
+ F/03 +

Unlimited Static QR Codes

+

Generate as many static QR codes as your project needs. Free forever with zero limits or expiration.

+
+
+
+
+ + +
+
+
+
+ 10 Transparent Pricing +

Choose the Perfect Plan

+

Simple pricing with no hidden fees. Upgrade or downgrade anytime.

+
+
All Plans Include Unlimited Static Codes
+
+ +
+
+ Monthly Billing + + Yearly Billing + Save 16% +
+
+ +
+
+
Free Plan
+
€0Forever
+
    +
  • 3 active dynamic QR codes (8 types)
  • +
  • Unlimited static QR codes
  • +
  • Basic scan tracking
  • +
  • Standard styling presets
  • +
  • High-res SVG & PNG export
  • +
+ Get Started Free +

No credit card required

+
+ + + +
+
Business Plan
+
€29per month
+
    +
  • 500 dynamic QR codes
  • +
  • Unlimited static QR codes
  • +
  • Everything in Pro
  • +
  • Bulk QR Generator (up to 1,000)
  • +
  • Priority support
  • +
+ Get Started +
+ +
+
Enterprise
+
Custom
+
    +
  • Unlimited dynamic QR codes
  • +
  • Unlimited static QR codes
  • +
  • Custom API integration
  • +
  • Dedicated Account Manager
  • +
  • SLA & custom contract
  • +
+ Contact Sales +
+
+

All plans include high-resolution vector export and full privacy compliance.

+
+
+ + +
+
+
+ 11 FAQ +

Frequently Asked Questions

+
+ +
+
+ +

No account is required to generate static QR codes. Dynamic QR codes with scan tracking and editing capabilities require a free account.

+
+
+ +

Static QR codes hold fixed data embedded directly in the code matrix. Dynamic QR codes route through a short URL so you can edit the destination anytime without reprinting.

+
+
+ +

Yes. Static QR codes contain raw data (like plain text or URLs) and never expire as long as the destination URL remains active.

+
+
+ +

For commercial print (flyers, signs, packaging), SVG is recommended because vector graphics scale losslessly to any size.

+
+
+ +

Yes. Scan analytics process aggregated technical metadata (country, device type) without storing personally identifiable user data.

+
+
+ + +
+
+ + +
+
+ 12 GET STARTED +

Your next QR code is 30 seconds away.

+

Static codes free forever. Dynamic codes with analytics starting at €0.

+ Create a QR Code Free + + +
+
+ + + + + + + + + + + + + diff --git a/design-variants/landing-classical.html b/design-variants/landing-classical.html new file mode 100644 index 0000000..e4c96f3 --- /dev/null +++ b/design-variants/landing-classical.html @@ -0,0 +1,2088 @@ + + + + + +QR Master — Classical — Design Variant + + + + + + + + + + + + + + + + + + + + + + +
+
+ + EST. 2026 · PLATE I Free Dynamic QR Code Generator +

Free Dynamic QR Code
Generator with Tracking

+

Create static and dynamic QR codes with editable destinations, scan analytics, custom branding, and bulk creation.

+
+ + + + + +
+
+ https://www.qrmaster.net + Live Specimen +
+ +
+ Select type: + URL + vCard + WiFi + PDF + Event + Coupon + App Store + Call +
+ +
+
+ + +
+
+
+
0/5
Customer Rating
+
0+
Verified Reviews
+
0
Free Specialized Tools
+
0
To Start Forever
+
+
+
+ + +
+
+
+
+ 01 Instant Studio +

Interactive QR Code Generator Studio

+

Type a URL or destination, pick colors, test WCAG contrast, and download SVG or PNG instantly without signup.

+
+
SVG + PNG : High-Res 300 DPI : 100% Free
+
+ +
+ +
+
+ + +
+ +
+ +
+ + + + + + +
+
+ +
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+
+ + +
+
+ + +
230px
+
+
+ +
+ Good contrast + WCAG Ratio: 16.2:1 +
+ +
+ + +
+ + Save & Track Analytics + + +
+ + +
+ Real-Time Studio Canvas +
+ + + + +
+ +
+
+
https://www.qrmaster.net
+
Scan with any smartphone camera
+
+
+
+
+ + +
+
+
+
+ 02 AI Innovation +

The future of QR codes is AI-powered

+

Next-generation intelligence for QR code generation, design optimization, and scan prediction.

+
+
In Active Development
+
+ +
+
+ A1 +

Smart QR Generation

+
    +
  • AI-powered content optimization
  • +
  • Intelligent design & color matching
  • +
  • Auto vCard creation from LinkedIn
  • +
  • SEO-optimized short URLs
  • +
+
+
+ A2 +

Predictive Analytics

+
    +
  • AI scan rate forecasting
  • +
  • Anomaly & fraud detection
  • +
  • Natural language analytics queries
  • +
  • Automated performance alerts
  • +
+
+
+ A3 +

Smart Content Hub

+
    +
  • Automated campaign tagging
  • +
  • Smart bulk CSV generation
  • +
  • AI fallback destination routing
  • +
  • Dynamic content personalization
  • +
+
+
+ A4 +

Creative Studio AI

+
    +
  • AI custom artistic QR designs
  • +
  • Auto-generated marketing copy
  • +
  • Automated A/B split testing
  • +
  • Print-ready layout checks
  • +
+
+
+ +
+
Get early access when AI features launch
+
+ + +
+

Join 1,400+ creators on the VIP access list

+
+ + You are on the list. We will notify you first! +
+
+
+
+ + +
+
+
+
+ 03 Tool Index +

18 Specialized Free QR Code Tools

+

Create dedicated QR codes for every use case. 100% free with no registration required.

+
+
18 Tools : No Account Needed
+
+ +
+ +
+ +
+
+
+ + +
+
+
+ 04 Workflows +

Popular QR Master Workflows

+

High-intent solutions for editable QR codes, spreadsheet batches, barcodes, meeting links, and local business campaigns.

+
+ +
+
+ + +
+
+
+ 05 Industry Guides +

QR Codes by Industry

+

Explore how modern teams use dynamic QR codes to track offline engagement and convert physical traffic.

+
+ + +
+
+ + +
+
+
+
+ 06 Social Proof +

Trusted by Businesses Worldwide

+

Real stories from restaurant owners, marketers, and designers using QR Master.

+
+
4.9/5 Rating : 12 Verified Reviews
+
+
+
+
+
+
+ Read All 12 Customer Stories + + +
+
+ + +
+
+
+
+ 07 Feature Comparison +

Why Dynamic QR Codes Save You Money

+

Stop re-printing physical materials every time a URL changes. Update destination links instantly and track every scan.

+
+
Static = Fixed Forever : Dynamic = Editable Forever
+
+ +
+
+
+
Static QR
Always Free
+
Dynamic QR
Recommended
+
+
+
Edit Destination URL Anytime
+
Fixed Forever
+
YES (Instant)
+
+
+
Real-Time Scan AnalyticsTime, device type, location
+
Not Available
+
YES
+
+
+
Custom Branding & Logo Overlay
+
Basic Only
+
YES
+
+
+
Bulk Creation from Excel/CSV
+
Manual Only
+
YES
+
+
+
No Account Required to CreateDynamic account signup takes under 60 seconds
+
YES
+
Free Account
+
+
+
+
+ + +
+
+
+
+ 08 Interactive ROI Calculator +

Are you burning budget on static reprints?

+

Estimate your annual print savings by switching from static printed codes to dynamic QR codes.

+ +
+ + +
+ +
+ + +
+ + Calculate Custom Campaign ROI + + +
+ +
+ Estimated Annual Savings + €1,125 + *Based on average €0.15 print cost per unit, industry estimate +
+
+
+
+ + +
+
+
+ 09 Platform Highlights +

Everything You Need for Professional QR Campaigns

+
+
+
+ F/01 +

Real-Time Scan Analytics

+

Track total scans, device breakdown, geographic locations, and time trends in an intuitive dashboard.

+
+
+ F/02 +

Full Brand Customization

+

Customize colors, corner styles, and add your company logo for seamless visual brand alignment.

+
+
+ F/03 +

Unlimited Static QR Codes

+

Generate as many static QR codes as your project needs. Free forever with zero limits or expiration.

+
+
+
+
+ + +
+
+
+
+ 10 Transparent Pricing +

Choose the Perfect Plan

+

Simple pricing with no hidden fees. Upgrade or downgrade anytime.

+
+
All Plans Include Unlimited Static Codes
+
+ +
+
+ Monthly Billing + + Yearly Billing + Save 16% +
+
+ +
+
+
Free Plan
+
€0Forever
+
    +
  • 3 active dynamic QR codes (8 types)
  • +
  • Unlimited static QR codes
  • +
  • Basic scan tracking
  • +
  • Standard styling presets
  • +
  • High-res SVG & PNG export
  • +
+ Get Started Free +

No credit card required

+
+ + + +
+
Business Plan
+
€29per month
+
    +
  • 500 dynamic QR codes
  • +
  • Unlimited static QR codes
  • +
  • Everything in Pro
  • +
  • Bulk QR Generator (up to 1,000)
  • +
  • Priority support
  • +
+ Get Started +
+ +
+
Enterprise
+
Custom
+
    +
  • Unlimited dynamic QR codes
  • +
  • Unlimited static QR codes
  • +
  • Custom API integration
  • +
  • Dedicated Account Manager
  • +
  • SLA & custom contract
  • +
+ Contact Sales +
+
+

All plans include high-resolution vector export and full privacy compliance.

+
+
+ + +
+
+
+ 11 FAQ +

Frequently Asked Questions

+
+ +
+
+ +

No account is required to generate static QR codes. Dynamic QR codes with scan tracking and editing capabilities require a free account.

+
+
+ +

Static QR codes hold fixed data embedded directly in the code matrix. Dynamic QR codes route through a short URL so you can edit the destination anytime without reprinting.

+
+
+ +

Yes. Static QR codes contain raw data (like plain text or URLs) and never expire as long as the destination URL remains active.

+
+
+ +

For commercial print (flyers, signs, packaging), SVG is recommended because vector graphics scale losslessly to any size.

+
+
+ +

Yes. Scan analytics process aggregated technical metadata (country, device type) without storing personally identifiable user data.

+
+
+ + +
+
+ + +
+
+ 12 GET STARTED +

Your next QR code is 30 seconds away.

+

Static codes free forever. Dynamic codes with analytics starting at €0.

+ Create a QR Code Free + + +
+
+ + + + + + + + + + + + + diff --git a/design-variants/landing-data-texture.html b/design-variants/landing-data-texture.html new file mode 100644 index 0000000..888a334 --- /dev/null +++ b/design-variants/landing-data-texture.html @@ -0,0 +1,2092 @@ + + + + + +QR Master — Data-Texture — Design Variant + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ SYS.STATUS :: LIVE Free Dynamic QR Code Generator +

Free Dynamic QR Code Generator with Tracking

+

Create static and dynamic QR codes with editable destinations, scan analytics, custom branding, and bulk creation.

+ +
+
+
LIVE SPECIMEN
+ + https://www.qrmaster.net +
+ URL + vCard + WiFi + PDF + Event + Coupon + App Store + Call +
+
+
+
+ No credit card required
+
+ Free forever static codes
+
+ Real-time scan analytics
+
+ Custom colors & branding
+
+
+
+ + +
+
+
+
0/5
Customer Rating
+
0+
Verified Reviews
+
0
Free Specialized Tools
+
0
To Start Forever
+
+
+
+ + +
+
+
+
+ 01 Instant Studio +

Interactive QR Code Generator Studio

+

Type a URL or destination, pick colors, test WCAG contrast, and download SVG or PNG instantly without signup.

+
+
SVG + PNG : High-Res 300 DPI : 100% Free
+
+ +
+ +
+
+ + +
+ +
+ +
+ + + + + + +
+
+ +
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+
+ + +
+
+ + +
230px
+
+
+ +
+ Good contrast + WCAG Ratio: 16.2:1 +
+ +
+ + +
+ + Save & Track Analytics + + +
+ + +
+ Real-Time Studio Canvas +
+ + + + +
+ +
+
+
https://www.qrmaster.net
+
Scan with any smartphone camera
+
+
+
+
+ + +
+
+
+
+ 02 AI Innovation +

The future of QR codes is AI-powered

+

Next-generation intelligence for QR code generation, design optimization, and scan prediction.

+
+
In Active Development
+
+ +
+
+ A1 +

Smart QR Generation

+
    +
  • AI-powered content optimization
  • +
  • Intelligent design & color matching
  • +
  • Auto vCard creation from LinkedIn
  • +
  • SEO-optimized short URLs
  • +
+
+
+ A2 +

Predictive Analytics

+
    +
  • AI scan rate forecasting
  • +
  • Anomaly & fraud detection
  • +
  • Natural language analytics queries
  • +
  • Automated performance alerts
  • +
+
+
+ A3 +

Smart Content Hub

+
    +
  • Automated campaign tagging
  • +
  • Smart bulk CSV generation
  • +
  • AI fallback destination routing
  • +
  • Dynamic content personalization
  • +
+
+
+ A4 +

Creative Studio AI

+
    +
  • AI custom artistic QR designs
  • +
  • Auto-generated marketing copy
  • +
  • Automated A/B split testing
  • +
  • Print-ready layout checks
  • +
+
+
+ +
+
Get early access when AI features launch
+
+ + +
+

Join 1,400+ creators on the VIP access list

+
+ + You are on the list. We will notify you first! +
+
+
+
+ + +
+
+
+
+ 03 Tool Index +

18 Specialized Free QR Code Tools

+

Create dedicated QR codes for every use case. 100% free with no registration required.

+
+
18 Tools : No Account Needed
+
+ +
+ +
+ +
+
+
+ + +
+
+
+ 04 Workflows +

Popular QR Master Workflows

+

High-intent solutions for editable QR codes, spreadsheet batches, barcodes, meeting links, and local business campaigns.

+
+ +
+
+ + +
+
+
+ 05 Industry Guides +

QR Codes by Industry

+

Explore how modern teams use dynamic QR codes to track offline engagement and convert physical traffic.

+
+ + +
+
+ + +
+
+
+
+ 06 Social Proof +

Trusted by Businesses Worldwide

+

Real stories from restaurant owners, marketers, and designers using QR Master.

+
+
4.9/5 Rating : 12 Verified Reviews
+
+
+
+
+
+
+ Read All 12 Customer Stories + + +
+
+ + +
+
+
+
+ 07 Feature Comparison +

Why Dynamic QR Codes Save You Money

+

Stop re-printing physical materials every time a URL changes. Update destination links instantly and track every scan.

+
+
Static = Fixed Forever : Dynamic = Editable Forever
+
+ +
+
+
+
Static QR
Always Free
+
Dynamic QR
Recommended
+
+
+
Edit Destination URL Anytime
+
Fixed Forever
+
YES (Instant)
+
+
+
Real-Time Scan AnalyticsTime, device type, location
+
Not Available
+
YES
+
+
+
Custom Branding & Logo Overlay
+
Basic Only
+
YES
+
+
+
Bulk Creation from Excel/CSV
+
Manual Only
+
YES
+
+
+
No Account Required to CreateDynamic account signup takes under 60 seconds
+
YES
+
Free Account
+
+
+
+
+ + +
+
+
+
+ 08 Interactive ROI Calculator +

Are you burning budget on static reprints?

+

Estimate your annual print savings by switching from static printed codes to dynamic QR codes.

+ +
+ + +
+ +
+ + +
+ + Calculate Custom Campaign ROI + + +
+ +
+ Estimated Annual Savings + €1,125 + *Based on average €0.15 print cost per unit, industry estimate +
+
+
+
+ + +
+
+
+ 09 Platform Highlights +

Everything You Need for Professional QR Campaigns

+
+
+
+ F/01 +

Real-Time Scan Analytics

+

Track total scans, device breakdown, geographic locations, and time trends in an intuitive dashboard.

+
+
+ F/02 +

Full Brand Customization

+

Customize colors, corner styles, and add your company logo for seamless visual brand alignment.

+
+
+ F/03 +

Unlimited Static QR Codes

+

Generate as many static QR codes as your project needs. Free forever with zero limits or expiration.

+
+
+
+
+ + +
+
+
+
+ 10 Transparent Pricing +

Choose the Perfect Plan

+

Simple pricing with no hidden fees. Upgrade or downgrade anytime.

+
+
All Plans Include Unlimited Static Codes
+
+ +
+
+ Monthly Billing + + Yearly Billing + Save 16% +
+
+ +
+
+
Free Plan
+
€0Forever
+
    +
  • 3 active dynamic QR codes (8 types)
  • +
  • Unlimited static QR codes
  • +
  • Basic scan tracking
  • +
  • Standard styling presets
  • +
  • High-res SVG & PNG export
  • +
+ Get Started Free +

No credit card required

+
+ + + +
+
Business Plan
+
€29per month
+
    +
  • 500 dynamic QR codes
  • +
  • Unlimited static QR codes
  • +
  • Everything in Pro
  • +
  • Bulk QR Generator (up to 1,000)
  • +
  • Priority support
  • +
+ Get Started +
+ +
+
Enterprise
+
Custom
+
    +
  • Unlimited dynamic QR codes
  • +
  • Unlimited static QR codes
  • +
  • Custom API integration
  • +
  • Dedicated Account Manager
  • +
  • SLA & custom contract
  • +
+ Contact Sales +
+
+

All plans include high-resolution vector export and full privacy compliance.

+
+
+ + +
+
+
+ 11 FAQ +

Frequently Asked Questions

+
+ +
+
+ +

No account is required to generate static QR codes. Dynamic QR codes with scan tracking and editing capabilities require a free account.

+
+
+ +

Static QR codes hold fixed data embedded directly in the code matrix. Dynamic QR codes route through a short URL so you can edit the destination anytime without reprinting.

+
+
+ +

Yes. Static QR codes contain raw data (like plain text or URLs) and never expire as long as the destination URL remains active.

+
+
+ +

For commercial print (flyers, signs, packaging), SVG is recommended because vector graphics scale losslessly to any size.

+
+
+ +

Yes. Scan analytics process aggregated technical metadata (country, device type) without storing personally identifiable user data.

+
+
+ + +
+
+ + +
+
+ 12 GET STARTED +

Your next QR code is 30 seconds away.

+

Static codes free forever. Dynamic codes with analytics starting at €0.

+ Create a QR Code Free + + +
+
+ + + + + + + + + + + + + diff --git a/design-variants/landing-dither-mono.html b/design-variants/landing-dither-mono.html new file mode 100644 index 0000000..ec25f51 --- /dev/null +++ b/design-variants/landing-dither-mono.html @@ -0,0 +1,2093 @@ + + + + + +QR Master — Dither Mono — Design Variant + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ HALFTONE · 85 LPI Free Dynamic QR Code Generator +

Free Dynamic QR Code Generator with Tracking

+

Create static and dynamic QR codes with editable destinations, scan analytics, custom branding, and bulk creation.

+ +
+
+
+ + https://www.qrmaster.net +
+
    +
  • + No credit card required
  • +
  • + Free forever static codes
  • +
  • + Real-time scan analytics
  • +
  • + Custom colors & branding
  • +
+
+ Select type: + URL + vCard + WiFi + PDF + Event + Coupon + App Store + Call +
+
+
+
+ + +
+
+
+
0/5
Customer Rating
+
0+
Verified Reviews
+
0
Free Specialized Tools
+
0
To Start Forever
+
+
+
+ + +
+
+
+
+ 01 Instant Studio +

Interactive QR Code Generator Studio

+

Type a URL or destination, pick colors, test WCAG contrast, and download SVG or PNG instantly without signup.

+
+
SVG + PNG : High-Res 300 DPI : 100% Free
+
+ +
+ +
+
+ + +
+ +
+ +
+ + + + + + +
+
+ +
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+
+ + +
+
+ + +
230px
+
+
+ +
+ Good contrast + WCAG Ratio: 16.2:1 +
+ +
+ + +
+ + Save & Track Analytics + + +
+ + +
+ Real-Time Studio Canvas +
+ + + + +
+ +
+
+
https://www.qrmaster.net
+
Scan with any smartphone camera
+
+
+
+
+ + +
+
+
+
+ 02 AI Innovation +

The future of QR codes is AI-powered

+

Next-generation intelligence for QR code generation, design optimization, and scan prediction.

+
+
In Active Development
+
+ +
+
+ A1 +

Smart QR Generation

+
    +
  • AI-powered content optimization
  • +
  • Intelligent design & color matching
  • +
  • Auto vCard creation from LinkedIn
  • +
  • SEO-optimized short URLs
  • +
+
+
+ A2 +

Predictive Analytics

+
    +
  • AI scan rate forecasting
  • +
  • Anomaly & fraud detection
  • +
  • Natural language analytics queries
  • +
  • Automated performance alerts
  • +
+
+
+ A3 +

Smart Content Hub

+
    +
  • Automated campaign tagging
  • +
  • Smart bulk CSV generation
  • +
  • AI fallback destination routing
  • +
  • Dynamic content personalization
  • +
+
+
+ A4 +

Creative Studio AI

+
    +
  • AI custom artistic QR designs
  • +
  • Auto-generated marketing copy
  • +
  • Automated A/B split testing
  • +
  • Print-ready layout checks
  • +
+
+
+ +
+
Get early access when AI features launch
+
+ + +
+

Join 1,400+ creators on the VIP access list

+
+ + You are on the list. We will notify you first! +
+
+
+
+ + +
+
+
+
+ 03 Tool Index +

18 Specialized Free QR Code Tools

+

Create dedicated QR codes for every use case. 100% free with no registration required.

+
+
18 Tools : No Account Needed
+
+ +
+ +
+ +
+
+
+ + +
+
+
+ 04 Workflows +

Popular QR Master Workflows

+

High-intent solutions for editable QR codes, spreadsheet batches, barcodes, meeting links, and local business campaigns.

+
+ +
+
+ + +
+
+
+ 05 Industry Guides +

QR Codes by Industry

+

Explore how modern teams use dynamic QR codes to track offline engagement and convert physical traffic.

+
+ + +
+
+ + +
+
+
+
+ 06 Social Proof +

Trusted by Businesses Worldwide

+

Real stories from restaurant owners, marketers, and designers using QR Master.

+
+
4.9/5 Rating : 12 Verified Reviews
+
+
+
+
+
+
+ Read All 12 Customer Stories + + +
+
+ + +
+
+
+
+ 07 Feature Comparison +

Why Dynamic QR Codes Save You Money

+

Stop re-printing physical materials every time a URL changes. Update destination links instantly and track every scan.

+
+
Static = Fixed Forever : Dynamic = Editable Forever
+
+ +
+
+
+
Static QR
Always Free
+
Dynamic QR
Recommended
+
+
+
Edit Destination URL Anytime
+
Fixed Forever
+
YES (Instant)
+
+
+
Real-Time Scan AnalyticsTime, device type, location
+
Not Available
+
YES
+
+
+
Custom Branding & Logo Overlay
+
Basic Only
+
YES
+
+
+
Bulk Creation from Excel/CSV
+
Manual Only
+
YES
+
+
+
No Account Required to CreateDynamic account signup takes under 60 seconds
+
YES
+
Free Account
+
+
+
+
+ + +
+
+
+
+ 08 Interactive ROI Calculator +

Are you burning budget on static reprints?

+

Estimate your annual print savings by switching from static printed codes to dynamic QR codes.

+ +
+ + +
+ +
+ + +
+ + Calculate Custom Campaign ROI + + +
+ +
+ Estimated Annual Savings + €1,125 + *Based on average €0.15 print cost per unit, industry estimate +
+
+
+
+ + +
+
+
+ 09 Platform Highlights +

Everything You Need for Professional QR Campaigns

+
+
+
+ F/01 +

Real-Time Scan Analytics

+

Track total scans, device breakdown, geographic locations, and time trends in an intuitive dashboard.

+
+
+ F/02 +

Full Brand Customization

+

Customize colors, corner styles, and add your company logo for seamless visual brand alignment.

+
+
+ F/03 +

Unlimited Static QR Codes

+

Generate as many static QR codes as your project needs. Free forever with zero limits or expiration.

+
+
+
+
+ + +
+
+
+
+ 10 Transparent Pricing +

Choose the Perfect Plan

+

Simple pricing with no hidden fees. Upgrade or downgrade anytime.

+
+
All Plans Include Unlimited Static Codes
+
+ +
+
+ Monthly Billing + + Yearly Billing + Save 16% +
+
+ +
+
+
Free Plan
+
€0Forever
+
    +
  • 3 active dynamic QR codes (8 types)
  • +
  • Unlimited static QR codes
  • +
  • Basic scan tracking
  • +
  • Standard styling presets
  • +
  • High-res SVG & PNG export
  • +
+ Get Started Free +

No credit card required

+
+ + + +
+
Business Plan
+
€29per month
+
    +
  • 500 dynamic QR codes
  • +
  • Unlimited static QR codes
  • +
  • Everything in Pro
  • +
  • Bulk QR Generator (up to 1,000)
  • +
  • Priority support
  • +
+ Get Started +
+ +
+
Enterprise
+
Custom
+
    +
  • Unlimited dynamic QR codes
  • +
  • Unlimited static QR codes
  • +
  • Custom API integration
  • +
  • Dedicated Account Manager
  • +
  • SLA & custom contract
  • +
+ Contact Sales +
+
+

All plans include high-resolution vector export and full privacy compliance.

+
+
+ + +
+
+
+ 11 FAQ +

Frequently Asked Questions

+
+ +
+
+ +

No account is required to generate static QR codes. Dynamic QR codes with scan tracking and editing capabilities require a free account.

+
+
+ +

Static QR codes hold fixed data embedded directly in the code matrix. Dynamic QR codes route through a short URL so you can edit the destination anytime without reprinting.

+
+
+ +

Yes. Static QR codes contain raw data (like plain text or URLs) and never expire as long as the destination URL remains active.

+
+
+ +

For commercial print (flyers, signs, packaging), SVG is recommended because vector graphics scale losslessly to any size.

+
+
+ +

Yes. Scan analytics process aggregated technical metadata (country, device type) without storing personally identifiable user data.

+
+
+ + +
+
+ + +
+
+ 12 GET STARTED +

Your next QR code is 30 seconds away.

+

Static codes free forever. Dynamic codes with analytics starting at €0.

+ Create a QR Code Free + + +
+
+ + + + + + + + + + + + + diff --git a/design-variants/landing-quiet-mono.html b/design-variants/landing-quiet-mono.html new file mode 100644 index 0000000..7abb633 --- /dev/null +++ b/design-variants/landing-quiet-mono.html @@ -0,0 +1,2319 @@ + + + + + +QR Master — Quiet Mono — Design Variant + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ +
+ HALFTONE ED. Free Dynamic QR Code Generator +

Free Dynamic QR Code Generator with Tracking

+

Create static and dynamic QR codes with editable destinations, scan analytics, custom branding, and bulk creation.

+ +
+
+ +
+
+
+ 01 +
+ +
+ https://www.qrmaster.net +
+
+ 02 +
    +
  • + No credit card required
  • +
  • + Free forever static codes
  • +
  • + Real-time scan analytics
  • +
  • + Custom colors & branding
  • +
+
+
+ 03 + Try it with +
+ URL + vCard + WiFi + PDF + Event + Coupon + App Store + Call +
+
+
+
+
+ + +
+
+
+
0/5
Customer Rating
+
0+
Verified Reviews
+
0
Free Specialized Tools
+
0
To Start Forever
+
+
+
+ + +
+
+
+
+ 01 Instant Studio +

Interactive QR Code Generator Studio

+

Type a URL or destination, pick colors, test WCAG contrast, and download SVG or PNG instantly without signup.

+
+
SVG + PNG : High-Res 300 DPI : 100% Free
+
+ +
+ +
+
+ + +
+ +
+ +
+ + + + + + +
+
+ +
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+
+ + +
+
+ + +
230px
+
+
+ +
+ Good contrast + WCAG Ratio: 16.2:1 +
+ +
+ + +
+ + Save & Track Analytics + + +
+ + +
+ Real-Time Studio Canvas +
+ + + + +
+ +
+
+
https://www.qrmaster.net
+
Scan with any smartphone camera
+
+
+
+
+ + +
+
+
+
+ 02 AI Innovation +

The future of QR codes is AI-powered

+

Next-generation intelligence for QR code generation, design optimization, and scan prediction.

+
+
In Active Development
+
+ +
+
+ A1 +

Smart QR Generation

+
    +
  • AI-powered content optimization
  • +
  • Intelligent design & color matching
  • +
  • Auto vCard creation from LinkedIn
  • +
  • SEO-optimized short URLs
  • +
+
+
+ A2 +

Predictive Analytics

+
    +
  • AI scan rate forecasting
  • +
  • Anomaly & fraud detection
  • +
  • Natural language analytics queries
  • +
  • Automated performance alerts
  • +
+
+
+ A3 +

Smart Content Hub

+
    +
  • Automated campaign tagging
  • +
  • Smart bulk CSV generation
  • +
  • AI fallback destination routing
  • +
  • Dynamic content personalization
  • +
+
+
+ A4 +

Creative Studio AI

+
    +
  • AI custom artistic QR designs
  • +
  • Auto-generated marketing copy
  • +
  • Automated A/B split testing
  • +
  • Print-ready layout checks
  • +
+
+
+ +
+
Get early access when AI features launch
+
+ + +
+

Join 1,400+ creators on the VIP access list

+
+ + You are on the list. We will notify you first! +
+
+
+
+ + +
+
+
+
+ 03 Tool Index +

18 Specialized Free QR Code Tools

+

Create dedicated QR codes for every use case. 100% free with no registration required.

+
+
18 Tools : No Account Needed
+
+ +
+ +
+ +
+
+
+ + +
+
+
+ 04 Workflows +

Popular QR Master Workflows

+

High-intent solutions for editable QR codes, spreadsheet batches, barcodes, meeting links, and local business campaigns.

+
+ +
+
+ + +
+
+
+ 05 Industry Guides +

QR Codes by Industry

+

Explore how modern teams use dynamic QR codes to track offline engagement and convert physical traffic.

+
+ + +
+
+ + +
+
+
+
+ 06 Social Proof +

Trusted by Businesses Worldwide

+

Real stories from restaurant owners, marketers, and designers using QR Master.

+
+
4.9/5 Rating : 12 Verified Reviews
+
+
+
+
+
+
+ Read All 12 Customer Stories + + +
+
+ + +
+
+
+
+ 07 Feature Comparison +

Why Dynamic QR Codes Save You Money

+

Stop re-printing physical materials every time a URL changes. Update destination links instantly and track every scan.

+
+
Static = Fixed Forever : Dynamic = Editable Forever
+
+ +
+
+
+
Static QR
Always Free
+
Dynamic QR
Recommended
+
+
+
Edit Destination URL Anytime
+
Fixed Forever
+
YES (Instant)
+
+
+
Real-Time Scan AnalyticsTime, device type, location
+
Not Available
+
YES
+
+
+
Custom Branding & Logo Overlay
+
Basic Only
+
YES
+
+
+
Bulk Creation from Excel/CSV
+
Manual Only
+
YES
+
+
+
No Account Required to CreateDynamic account signup takes under 60 seconds
+
YES
+
Free Account
+
+
+
+
+ + +
+
+
+
+ 08 Interactive ROI Calculator +

Are you burning budget on static reprints?

+

Estimate your annual print savings by switching from static printed codes to dynamic QR codes.

+ +
+ + +
+ +
+ + +
+ + Calculate Custom Campaign ROI + + +
+ +
+ Estimated Annual Savings + €1,125 + *Based on average €0.15 print cost per unit, industry estimate +
+
+
+
+ + +
+
+
+ 09 Platform Highlights +

Everything You Need for Professional QR Campaigns

+
+
+
+ F/01 +

Real-Time Scan Analytics

+

Track total scans, device breakdown, geographic locations, and time trends in an intuitive dashboard.

+
+
+ F/02 +

Full Brand Customization

+

Customize colors, corner styles, and add your company logo for seamless visual brand alignment.

+
+
+ F/03 +

Unlimited Static QR Codes

+

Generate as many static QR codes as your project needs. Free forever with zero limits or expiration.

+
+
+
+
+ + +
+
+
+
+ 10 Transparent Pricing +

Choose the Perfect Plan

+

Simple pricing with no hidden fees. Upgrade or downgrade anytime.

+
+
All Plans Include Unlimited Static Codes
+
+ +
+
+ Monthly Billing + + Yearly Billing + Save 16% +
+
+ +
+
+
Free Plan
+
€0Forever
+
    +
  • 3 active dynamic QR codes (8 types)
  • +
  • Unlimited static QR codes
  • +
  • Basic scan tracking
  • +
  • Standard styling presets
  • +
  • High-res SVG & PNG export
  • +
+ Get Started Free +

No credit card required

+
+ + + +
+
Business Plan
+
€29per month
+
    +
  • 500 dynamic QR codes
  • +
  • Unlimited static QR codes
  • +
  • Everything in Pro
  • +
  • Bulk QR Generator (up to 1,000)
  • +
  • Priority support
  • +
+ Get Started +
+ +
+
Enterprise
+
Custom
+
    +
  • Unlimited dynamic QR codes
  • +
  • Unlimited static QR codes
  • +
  • Custom API integration
  • +
  • Dedicated Account Manager
  • +
  • SLA & custom contract
  • +
+ Contact Sales +
+
+

All plans include high-resolution vector export and full privacy compliance.

+
+
+ + +
+
+
+ 11 FAQ +

Frequently Asked Questions

+
+ +
+
+ +

No account is required to generate static QR codes. Dynamic QR codes with scan tracking and editing capabilities require a free account.

+
+
+ +

Static QR codes hold fixed data embedded directly in the code matrix. Dynamic QR codes route through a short URL so you can edit the destination anytime without reprinting.

+
+
+ +

Yes. Static QR codes contain raw data (like plain text or URLs) and never expire as long as the destination URL remains active.

+
+
+ +

For commercial print (flyers, signs, packaging), SVG is recommended because vector graphics scale losslessly to any size.

+
+
+ +

Yes. Scan analytics process aggregated technical metadata (country, device type) without storing personally identifiable user data.

+
+
+ + +
+
+ + +
+
+ 12 GET STARTED +

Your next QR code is 30 seconds away.

+

Static codes free forever. Dynamic codes with analytics starting at €0.

+ Create a QR Code Free + + +
+
+ + + + + + + + + + + + + diff --git a/design-variants/landing-vast-quiet.html b/design-variants/landing-vast-quiet.html new file mode 100644 index 0000000..2414a1d --- /dev/null +++ b/design-variants/landing-vast-quiet.html @@ -0,0 +1,2085 @@ + + + + + +QR Master — Vast Quiet — Design Variant + + + + + + + + + + + + + + + + + + + + + + +
+
+ EDITION No. 01 Free Dynamic QR Code Generator +

Free Dynamic QR Code Generator with Tracking

+

Create static and dynamic QR codes with editable destinations, scan analytics, custom branding, and bulk creation.

+ + +
+ Try it with + URL + vCard + WiFi + PDF + Event + Coupon + App Store + Call +
+ +
+
+ +
+ https://www.qrmaster.net +
+
+
+ + +
+
+
+
0/5
Customer Rating
+
0+
Verified Reviews
+
0
Free Specialized Tools
+
0
To Start Forever
+
+
+
+ + +
+
+
+
+ 01 Instant Studio +

Interactive QR Code Generator Studio

+

Type a URL or destination, pick colors, test WCAG contrast, and download SVG or PNG instantly without signup.

+
+
SVG + PNG : High-Res 300 DPI : 100% Free
+
+ +
+ +
+
+ + +
+ +
+ +
+ + + + + + +
+
+ +
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+
+ + +
+
+ + +
230px
+
+
+ +
+ Good contrast + WCAG Ratio: 16.2:1 +
+ +
+ + +
+ + Save & Track Analytics + + +
+ + +
+ Real-Time Studio Canvas +
+ + + + +
+ +
+
+
https://www.qrmaster.net
+
Scan with any smartphone camera
+
+
+
+
+ + +
+
+
+
+ 02 AI Innovation +

The future of QR codes is AI-powered

+

Next-generation intelligence for QR code generation, design optimization, and scan prediction.

+
+
In Active Development
+
+ +
+
+ A1 +

Smart QR Generation

+
    +
  • AI-powered content optimization
  • +
  • Intelligent design & color matching
  • +
  • Auto vCard creation from LinkedIn
  • +
  • SEO-optimized short URLs
  • +
+
+
+ A2 +

Predictive Analytics

+
    +
  • AI scan rate forecasting
  • +
  • Anomaly & fraud detection
  • +
  • Natural language analytics queries
  • +
  • Automated performance alerts
  • +
+
+
+ A3 +

Smart Content Hub

+
    +
  • Automated campaign tagging
  • +
  • Smart bulk CSV generation
  • +
  • AI fallback destination routing
  • +
  • Dynamic content personalization
  • +
+
+
+ A4 +

Creative Studio AI

+
    +
  • AI custom artistic QR designs
  • +
  • Auto-generated marketing copy
  • +
  • Automated A/B split testing
  • +
  • Print-ready layout checks
  • +
+
+
+ +
+
Get early access when AI features launch
+
+ + +
+

Join 1,400+ creators on the VIP access list

+
+ + You are on the list. We will notify you first! +
+
+
+
+ + +
+
+
+
+ 03 Tool Index +

18 Specialized Free QR Code Tools

+

Create dedicated QR codes for every use case. 100% free with no registration required.

+
+
18 Tools : No Account Needed
+
+ +
+ +
+ +
+
+
+ + +
+
+
+ 04 Workflows +

Popular QR Master Workflows

+

High-intent solutions for editable QR codes, spreadsheet batches, barcodes, meeting links, and local business campaigns.

+
+ +
+
+ + +
+
+
+ 05 Industry Guides +

QR Codes by Industry

+

Explore how modern teams use dynamic QR codes to track offline engagement and convert physical traffic.

+
+ + +
+
+ + +
+
+
+
+ 06 Social Proof +

Trusted by Businesses Worldwide

+

Real stories from restaurant owners, marketers, and designers using QR Master.

+
+
4.9/5 Rating : 12 Verified Reviews
+
+
+
+
+
+
+ Read All 12 Customer Stories + + +
+
+ + +
+
+
+
+ 07 Feature Comparison +

Why Dynamic QR Codes Save You Money

+

Stop re-printing physical materials every time a URL changes. Update destination links instantly and track every scan.

+
+
Static = Fixed Forever : Dynamic = Editable Forever
+
+ +
+
+
+
Static QR
Always Free
+
Dynamic QR
Recommended
+
+
+
Edit Destination URL Anytime
+
Fixed Forever
+
YES (Instant)
+
+
+
Real-Time Scan AnalyticsTime, device type, location
+
Not Available
+
YES
+
+
+
Custom Branding & Logo Overlay
+
Basic Only
+
YES
+
+
+
Bulk Creation from Excel/CSV
+
Manual Only
+
YES
+
+
+
No Account Required to CreateDynamic account signup takes under 60 seconds
+
YES
+
Free Account
+
+
+
+
+ + +
+
+
+
+ 08 Interactive ROI Calculator +

Are you burning budget on static reprints?

+

Estimate your annual print savings by switching from static printed codes to dynamic QR codes.

+ +
+ + +
+ +
+ + +
+ + Calculate Custom Campaign ROI + + +
+ +
+ Estimated Annual Savings + €1,125 + *Based on average €0.15 print cost per unit, industry estimate +
+
+
+
+ + +
+
+
+ 09 Platform Highlights +

Everything You Need for Professional QR Campaigns

+
+
+
+ F/01 +

Real-Time Scan Analytics

+

Track total scans, device breakdown, geographic locations, and time trends in an intuitive dashboard.

+
+
+ F/02 +

Full Brand Customization

+

Customize colors, corner styles, and add your company logo for seamless visual brand alignment.

+
+
+ F/03 +

Unlimited Static QR Codes

+

Generate as many static QR codes as your project needs. Free forever with zero limits or expiration.

+
+
+
+
+ + +
+
+
+
+ 10 Transparent Pricing +

Choose the Perfect Plan

+

Simple pricing with no hidden fees. Upgrade or downgrade anytime.

+
+
All Plans Include Unlimited Static Codes
+
+ +
+
+ Monthly Billing + + Yearly Billing + Save 16% +
+
+ +
+
+
Free Plan
+
€0Forever
+
    +
  • 3 active dynamic QR codes (8 types)
  • +
  • Unlimited static QR codes
  • +
  • Basic scan tracking
  • +
  • Standard styling presets
  • +
  • High-res SVG & PNG export
  • +
+ Get Started Free +

No credit card required

+
+ + + +
+
Business Plan
+
€29per month
+
    +
  • 500 dynamic QR codes
  • +
  • Unlimited static QR codes
  • +
  • Everything in Pro
  • +
  • Bulk QR Generator (up to 1,000)
  • +
  • Priority support
  • +
+ Get Started +
+ +
+
Enterprise
+
Custom
+
    +
  • Unlimited dynamic QR codes
  • +
  • Unlimited static QR codes
  • +
  • Custom API integration
  • +
  • Dedicated Account Manager
  • +
  • SLA & custom contract
  • +
+ Contact Sales +
+
+

All plans include high-resolution vector export and full privacy compliance.

+
+
+ + +
+
+
+ 11 FAQ +

Frequently Asked Questions

+
+ +
+
+ +

No account is required to generate static QR codes. Dynamic QR codes with scan tracking and editing capabilities require a free account.

+
+
+ +

Static QR codes hold fixed data embedded directly in the code matrix. Dynamic QR codes route through a short URL so you can edit the destination anytime without reprinting.

+
+
+ +

Yes. Static QR codes contain raw data (like plain text or URLs) and never expire as long as the destination URL remains active.

+
+
+ +

For commercial print (flyers, signs, packaging), SVG is recommended because vector graphics scale losslessly to any size.

+
+
+ +

Yes. Scan analytics process aggregated technical metadata (country, device type) without storing personally identifiable user data.

+
+
+ + +
+
+ + +
+
+ 12 GET STARTED +

Your next QR code is 30 seconds away.

+

Static codes free forever. Dynamic codes with analytics starting at €0.

+ Create a QR Code Free + + +
+
+ + + + + + + + + + + + + diff --git a/landing-design-v2.html b/landing-design-v2.html new file mode 100644 index 0000000..b769843 --- /dev/null +++ b/landing-design-v2.html @@ -0,0 +1,2082 @@ + + + + + +QR Master: Free Dynamic QR Code Generator with Tracking + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+ BLUEPRINT 3.0 Free Dynamic QR Code Generator +

Free Dynamic QR Code Generator with Tracking

+

+ Create static and dynamic QR codes with editable destinations, scan analytics, custom branding, and bulk creation. +

+
    +
  • + No credit card required
  • +
  • + Free forever static codes
  • +
  • + Real-time scan analytics
  • +
  • + Custom colors & branding
  • +
+ +
+ Select type: + URL + vCard + WiFi + PDF + Event + Coupon + App Store + Call +
+
+ + +
+ + +
+ + + + + + +
+
+ https://www.qrmaster.net + Live Specimen +
+
+
+
+ + +
+
+
+
0/5
Customer Rating
+
0+
Verified Reviews
+
0
Free Specialized Tools
+
0
To Start Forever
+
+
+
+ + +
+
+
+
+ 01 Instant Studio +

Interactive QR Code Generator Studio

+

Type a URL or destination, pick colors, test WCAG contrast, and download SVG or PNG instantly without signup.

+
+
SVG + PNG : High-Res 300 DPI : 100% Free
+
+ +
+ +
+
+ + +
+ +
+ +
+ + + + + + +
+
+ +
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+
+ + +
+
+ + +
230px
+
+
+ +
+ Good contrast + WCAG Ratio: 16.2:1 +
+ +
+ + +
+ + Save & Track Analytics + + +
+ + +
+ Real-Time Studio Canvas +
+ + + + +
+ +
+
+
https://www.qrmaster.net
+
Scan with any smartphone camera
+
+
+
+
+ + +
+
+
+
+ 02 AI Innovation +

The future of QR codes is AI-powered

+

Next-generation intelligence for QR code generation, design optimization, and scan prediction.

+
+
In Active Development
+
+ +
+
+ A1 +

Smart QR Generation

+
    +
  • AI-powered content optimization
  • +
  • Intelligent design & color matching
  • +
  • Auto vCard creation from LinkedIn
  • +
  • SEO-optimized short URLs
  • +
+
+
+ A2 +

Predictive Analytics

+
    +
  • AI scan rate forecasting
  • +
  • Anomaly & fraud detection
  • +
  • Natural language analytics queries
  • +
  • Automated performance alerts
  • +
+
+
+ A3 +

Smart Content Hub

+
    +
  • Automated campaign tagging
  • +
  • Smart bulk CSV generation
  • +
  • AI fallback destination routing
  • +
  • Dynamic content personalization
  • +
+
+
+ A4 +

Creative Studio AI

+
    +
  • AI custom artistic QR designs
  • +
  • Auto-generated marketing copy
  • +
  • Automated A/B split testing
  • +
  • Print-ready layout checks
  • +
+
+
+ +
+
Get early access when AI features launch
+
+ + +
+

Join 1,400+ creators on the VIP access list

+
+ + You are on the list. We will notify you first! +
+
+
+
+ + +
+
+
+
+ 03 Tool Index +

18 Specialized Free QR Code Tools

+

Create dedicated QR codes for every use case. 100% free with no registration required.

+
+
18 Tools : No Account Needed
+
+ +
+ +
+ +
+
+
+ + +
+
+
+ 04 Workflows +

Popular QR Master Workflows

+

High-intent solutions for editable QR codes, spreadsheet batches, barcodes, meeting links, and local business campaigns.

+
+ +
+
+ + +
+
+
+ 05 Industry Guides +

QR Codes by Industry

+

Explore how modern teams use dynamic QR codes to track offline engagement and convert physical traffic.

+
+ + +
+
+ + +
+
+
+
+ 06 Social Proof +

Trusted by Businesses Worldwide

+

Real stories from restaurant owners, marketers, and designers using QR Master.

+
+
4.9/5 Rating : 12 Verified Reviews
+
+
+
+
+
+
+ Read All 12 Customer Stories + + +
+
+ + +
+
+
+
+ 07 Feature Comparison +

Why Dynamic QR Codes Save You Money

+

Stop re-printing physical materials every time a URL changes. Update destination links instantly and track every scan.

+
+
Static = Fixed Forever : Dynamic = Editable Forever
+
+ +
+
+
+
Static QR
Always Free
+
Dynamic QR
Recommended
+
+
+
Edit Destination URL Anytime
+
Fixed Forever
+
YES (Instant)
+
+
+
Real-Time Scan AnalyticsTime, device type, location
+
Not Available
+
YES
+
+
+
Custom Branding & Logo Overlay
+
Basic Only
+
YES
+
+
+
Bulk Creation from Excel/CSV
+
Manual Only
+
YES
+
+
+
No Account Required to CreateDynamic account signup takes under 60 seconds
+
YES
+
Free Account
+
+
+
+
+ + +
+
+
+
+ 08 Interactive ROI Calculator +

Are you burning budget on static reprints?

+

Estimate your annual print savings by switching from static printed codes to dynamic QR codes.

+ +
+ + +
+ +
+ + +
+ + Calculate Custom Campaign ROI + + +
+ +
+ Estimated Annual Savings + €1,125 + *Based on average €0.15 print cost per unit, industry estimate +
+
+
+
+ + +
+
+
+ 09 Platform Highlights +

Everything You Need for Professional QR Campaigns

+
+
+
+ F/01 +

Real-Time Scan Analytics

+

Track total scans, device breakdown, geographic locations, and time trends in an intuitive dashboard.

+
+
+ F/02 +

Full Brand Customization

+

Customize colors, corner styles, and add your company logo for seamless visual brand alignment.

+
+
+ F/03 +

Unlimited Static QR Codes

+

Generate as many static QR codes as your project needs. Free forever with zero limits or expiration.

+
+
+
+
+ + +
+
+
+
+ 10 Transparent Pricing +

Choose the Perfect Plan

+

Simple pricing with no hidden fees. Upgrade or downgrade anytime.

+
+
All Plans Include Unlimited Static Codes
+
+ +
+
+ Monthly Billing + + Yearly Billing + Save 16% +
+
+ +
+
+
Free Plan
+
€0Forever
+
    +
  • 3 active dynamic QR codes (8 types)
  • +
  • Unlimited static QR codes
  • +
  • Basic scan tracking
  • +
  • Standard styling presets
  • +
  • High-res SVG & PNG export
  • +
+ Get Started Free +

No credit card required

+
+ + + +
+
Business Plan
+
€29per month
+
    +
  • 500 dynamic QR codes
  • +
  • Unlimited static QR codes
  • +
  • Everything in Pro
  • +
  • Bulk QR Generator (up to 1,000)
  • +
  • Priority support
  • +
+ Get Started +
+ +
+
Enterprise
+
Custom
+
    +
  • Unlimited dynamic QR codes
  • +
  • Unlimited static QR codes
  • +
  • Custom API integration
  • +
  • Dedicated Account Manager
  • +
  • SLA & custom contract
  • +
+ Contact Sales +
+
+

All plans include high-resolution vector export and full privacy compliance.

+
+
+ + +
+
+
+ 11 FAQ +

Frequently Asked Questions

+
+ +
+
+ +

No account is required to generate static QR codes. Dynamic QR codes with scan tracking and editing capabilities require a free account.

+
+
+ +

Static QR codes hold fixed data embedded directly in the code matrix. Dynamic QR codes route through a short URL so you can edit the destination anytime without reprinting.

+
+
+ +

Yes. Static QR codes contain raw data (like plain text or URLs) and never expire as long as the destination URL remains active.

+
+
+ +

For commercial print (flyers, signs, packaging), SVG is recommended because vector graphics scale losslessly to any size.

+
+
+ +

Yes. Scan analytics process aggregated technical metadata (country, device type) without storing personally identifiable user data.

+
+
+ + +
+
+ + +
+
+ 12 GET STARTED +

Your next QR code is 30 seconds away.

+

Static codes free forever. Dynamic codes with analytics starting at €0.

+ Create a QR Code Free + + +
+
+ + + + + + + + + + + + + diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 3f4006c..7625d65 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -33,9 +33,11 @@ model User { resetPasswordExpires DateTime? // Retention email tracking - activationNudgeSentAt DateTime? - upgradeNudgeSentAt DateTime? - thirtyDayNudgeSentAt DateTime? + activationNudgeSentAt DateTime? + upgradeNudgeSentAt DateTime? + thirtyDayNudgeSentAt DateTime? + limitReachedNudgeSentAt DateTime? + firstScanNudgeSentAt DateTime? // RevOps attribution signupSource String? @@ -69,18 +71,19 @@ model User { onboardingCompletedAt DateTime? // RevOps scoring - fitScore Int @default(0) - intentScore Int @default(0) - leadScore Int @default(0) - lifecycleStage String @default("cold") + fitScore Int @default(0) + intentScore Int @default(0) + leadScore Int @default(0) + lifecycleStage String @default("cold") lastQualifiedAt DateTime? lastScoredAt DateTime? - qrCodes QRCode[] - integrations Integration[] - accounts Account[] - sessions Session[] - lifecycleLogs UserLifecycleLog[] + qrCodes QRCode[] + designPresets QRDesignPreset[] + integrations Integration[] + accounts Account[] + sessions Session[] + lifecycleLogs UserLifecycleLog[] } enum Plan { @@ -142,6 +145,7 @@ model QRCode { scans QRScan[] @@index([userId, createdAt]) + @@index([userId, type, status]) } enum QRType { @@ -170,19 +174,19 @@ enum QRStatus { } model QRScan { - id String @id @default(cuid()) - qrId String - ts DateTime @default(now()) - ipHash String - userAgent String? - device String? - os String? - country String? - referrer String? - utmSource String? - utmMedium String? - utmCampaign String? - isUnique Boolean @default(false) + id String @id @default(cuid()) + qrId String + ts DateTime @default(now()) + ipHash String + userAgent String? + device String? + os String? + country String? + referrer String? + utmSource String? + utmMedium String? + utmCampaign String? + isUnique Boolean @default(false) qr QRCode @relation(fields: [qrId], references: [id], onDelete: Cascade) @@ -222,16 +226,32 @@ model SocialAsset { createdAt DateTime @default(now()) } +/// Saved design presets. The point for an agency is not the star shape, it is +/// that client A looks identical across 500 codes. +model QRDesignPreset { + id String @id @default(cuid()) + userId String + name String + style Json + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + + @@unique([userId, name]) + @@index([userId]) +} + model UserLifecycleLog { - id String @id @default(cuid()) - userId String - fromStage String? - toStage String - fitScore Int @default(0) - intentScore Int @default(0) - leadScore Int @default(0) - reason String? - createdAt DateTime @default(now()) + id String @id @default(cuid()) + userId String + fromStage String? + toStage String + fitScore Int @default(0) + intentScore Int @default(0) + leadScore Int @default(0) + reason String? + createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id], onDelete: Cascade) } diff --git a/public/favicon.ico b/public/favicon.ico index 5a198d0..ede6ea8 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/favicon.svg b/public/favicon.svg index b049bca..ea58114 100644 --- a/public/favicon.svg +++ b/public/favicon.svg @@ -1,32 +1,3 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + \ No newline at end of file diff --git a/public/favicon_sticker.png b/public/favicon_sticker.png new file mode 100644 index 0000000..a0c6625 Binary files /dev/null and b/public/favicon_sticker.png differ diff --git a/public/logo.svg b/public/logo.svg index 97d3f3f..4e81872 100644 --- a/public/logo.svg +++ b/public/logo.svg @@ -1,32 +1,3 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/qr-design-showcase.html b/qr-design-showcase.html new file mode 100644 index 0000000..f21d0bd --- /dev/null +++ b/qr-design-showcase.html @@ -0,0 +1,1044 @@ + + + + + +QR Code Design Showcase + + + + + +
+

QR Code Design Showcase

+

Ein Baukasten für QR-Code-Designs — Modulformen, Ecken-Stile, Farbverläufe, Rahmen, Logos & mehr. Klick auf eine Karte, um sie in den Editor zu laden.

+
+ +
+
+ +
+
Inhalt
+
+ + +
+
+ + +
+
+ +
+
Formen
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ +
+
Farben
+
+ + +
+
+
+ + +
+
+ + +
+
+
+ + +
+ + +
+ + +
+
+ +
+
Rahmen & Label
+
+ + +
+ +
+ +
+
Logo in der Mitte
+
+ + +
+
+
+ + +
+
+ + +
+
+
+ +
+
Feintuning
+
+
+ + +
+
+ + +
+
+ + +
+
+
+ +
+ +
+
+ +
+
+ + +
+
+
+ +

Design-Galerie Varianten — anklicken zum Übernehmen

+ + + + + + + diff --git a/qr-master-design.html b/qr-master-design.html new file mode 100644 index 0000000..e531f2a --- /dev/null +++ b/qr-master-design.html @@ -0,0 +1,1782 @@ + + + + + +QR Master - Free Dynamic QR Code Generator + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ Free QR code generator +

Codes that keep working after you print them.

+

Create a QR code in seconds, then edit where it points anytime. No account needed to start.

+ +
+
+
+ + + + + +
+ Live preview +
+
https://www.qrmaster.net
+
+
+ URL + vCard + WiFi + Event + Call +
+
+
+
+ + +
+
+
+
0/5
Customer rating
+
0+
Verified reviews
+
0
Free specialized tools
+
0
To start, forever
+
+
+
+ + +
+
+
+

Build your first code here.

+

Type a destination, pick colors, check WCAG contrast, and download SVG or PNG. No signup, no watermark.

+
+
+
+
+ + +
+
+ +
+ + + + + +
+
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+
+ + +
+
+ + +
230px
+
+
+
+ Good contrast + WCAG ratio: 16.2:1 +
+
+ + +
+ Save and track scans + + +
+
+
+ + + + +
+ +
+
+
https://www.qrmaster.net
+
Scan with any smartphone camera
+
+
+
+
+ + +
+
+
+

What you get for free.

+
+
+
+

Edit the destination anytime, without reprinting anything.

+

Dynamic codes route through a short link you control, so the printed code never has to change.

+
+
+
3
+
Dynamic codes on the free plan
+
+
+
18
+
Free specialized generators
+
+
+

See every tool, from WiFi to barcodes.

+ Browse tools + + +
+
+
+
+ + +
+
+
+

Every QR type, one generator.

+

18 dedicated tools for every destination. No account required for any of them.

+
+
+ +
+
+
+
+ + +
+
+
+

Popular ways to use QR Master.

+

Real workflows from restaurants, hotels, agencies, and event teams already running on dynamic codes.

+
+ + +
+
+ + +
+
+
+
+

See what static reprints are costing you.

+

Estimate your annual print savings by switching from static printed codes to dynamic ones.

+
+ + +
+
+ + +
+ Calculate your campaign + + +
+
+ Estimated annual savings + €1,125 + Based on an average €0.15 print cost per unit +
+
+
+
+ + +
+
+
+

Why switch to dynamic.

+

Stop reprinting physical materials every time a destination changes.

+
+
+
+
+
Static
Always free
+
Dynamic
Recommended
+
+
+
Edit the destination anytimeNo reprint required
+
Fixed forever
+
Instant
+
+
+
Scan analyticsTime, device, location
+
Not available
+
Included
+
+
+
Custom branding and logo overlay
+
Basic only
+
Full support
+
+
+
Bulk creation from a spreadsheet
+
Manual only
+
Included
+
+
+
Account required to createTakes under a minute
+
No
+
Free account
+
+
+
+
+ + +
+
+
+

What people are actually saying.

+
+
+
+
+
+
+ + +
+
+
+ Simple pricing +

Choose the plan that fits.

+

No hidden fees. Upgrade or downgrade whenever you need to.

+
+
+
+ Monthly + + Yearly + Save 16% +
+
+
+
+
Free
+
€0Forever
+
    +
  • 3 active dynamic codes, 8 types
  • +
  • Unlimited static codes
  • +
  • Basic scan tracking
  • +
  • High-res SVG and PNG export
  • +
+ Get started free +
+ +
+
Business
+
€29per month
+
    +
  • 500 dynamic codes
  • +
  • Everything in Pro
  • +
  • Bulk generator, up to 1,000 codes
  • +
  • Priority support
  • +
+ Get started +
+
+
Enterprise
+
Custom
+
    +
  • Unlimited dynamic codes
  • +
  • Custom API integration
  • +
  • Dedicated account manager
  • +
  • SLA and custom contract
  • +
+ Contact sales +
+
+
+
+ + +
+
+
+

Common questions.

+
+
+
+ +

No. Static codes can be created without an account. Dynamic codes, which support editing and scan tracking, need a free account.

+
+
+ +

A static code holds its destination directly in the pattern. A dynamic code routes through a short link, so you can change where it points without changing the printed code.

+
+
+ +

No. A static code holds plain data and keeps working for as long as the destination itself stays active.

+
+
+ +

SVG, for commercial print. It scales to any size without losing sharpness.

+
+
+ +

Yes. Scan analytics use aggregated technical metadata, such as country and device type, and never store personal data.

+
+
+
+
+ + +
+
+

Your first code is thirty seconds away.

+

Static codes are free forever. Dynamic codes with analytics start at €0.

+ Create a QR code + + +
+
+ + + + + + + + + + + + diff --git a/reports/seo-improver/2026-07-26/dataforseo-drei-domains.md b/reports/seo-improver/2026-07-26/dataforseo-drei-domains.md new file mode 100644 index 0000000..ec4d05d --- /dev/null +++ b/reports/seo-improver/2026-07-26/dataforseo-drei-domains.md @@ -0,0 +1,165 @@ +# DataForSEO SEO-Analyse – QRMaster, GreenLens Pro, Entscheidomat + +**Datum:** 2026-07-26 +**Quelle:** DataForSEO API v3, Google Labs / Ranked Keywords / Competitors Domain / Domain Intersection + +## Untersuchungsumfang + +| Domain | Markt / Sprache | Ranked Keywords | Wettbewerberdaten | +|---|---|---:|---| +| qrmaster.net | Deutschland / Deutsch | 3 | erfolgreich | +| qrmaster.net | USA / Englisch | 100 | erfolgreich | +| greenlenspro.com | USA / Englisch | 100 | erfolgreich | +| entscheidomat.com | Deutschland / Deutsch | 0 | keine Rankingdaten | + +Die Werte sind eine DataForSEO-Momentaufnahme und kein Ersatz für Google Search Console. Rankingdaten wurden als organische Google-Daten abgerufen. + +## 1. QRMaster + +### Deutschland / Deutsch + +Aktuell gemessene Rankings: + +- `qr codes tracking` – Position 97, Suchvolumen 210, `/qr-code-tracking` +- `qr-code karten` – Position 52, Suchvolumen 110, `/de/qr-codes-fuer-visitenkarten` +- `dynamic qr code generator` – Position 38, Suchvolumen 90, `/dynamic-qr-code-generator` + +Wichtig: Die Rankingdaten enthalten kaum deutschsprachige Kernbegriffe. Das spricht eher für ein Content-/Lokalisierungsproblem als für ein reines Technikproblem. + +### USA / Englisch + +Stärkste aktuell gefundene Themen: + +- `generate a barcode free` – Volumen 40.500, Position 98, `/tools/barcode-generator` +- `visiting card with qr code` – 12.100, Position 107, `/use-cases/business-card-qr-codes` +- `barcode design online` – 9.900, Position 104, `/tools/barcode-generator` +- `create a qr code for a url` / `create qr code from url` – je 8.100, Position 93/91 +- `qr code generator for url` – 8.100, Position 68 +- `bitly qr` – 2.900, Position 28, `/alternatives/bitly` +- `flowcode qr` – 2.400, Position 31, `/alternatives/flowcode` +- `vcard qr generator` – 1.300, Position 31, `/tools/vcard-qr-code` +- `vcard qr code generator` – 1.300, Position 89 + +### Wichtigste Wettbewerber + +**Deutschland:** qrcode-generator.de, me-qr.com, pageloot.com, qrcodechimp.com, qrcode-tiger.com, qrcodekit.com, the-qrcode-generator.com, qrfy.com, qrcode-monkey.com. + +**USA:** qr-code-generator.com, me-qr.com, qrcodechimp.com, the-qrcode-generator.com, qrstuff.com, uniqode.com, scanova.io, viralqr.com. + +### Keyword-Gaps / Chancen + +Die Domain-Intersection-Abfragen zeigen, dass Wettbewerber unter anderem für folgende relevante Themen ranken, während QRMaster in den abgefragten SERPs nicht gleichzeitig auftaucht: + +- `qr code generator`, `generate a qr code`, `qr code builder` +- `qr codes erstellen`, `qr-code erstellen`, `qr-code erzeugen` +- `qr code scanner`, `qr code scannen` +- `qr codes erstellen kostenlos` +- `dynamic qr code`, `dynamic qr code generator` +- `qr code tracking`, `qr code analytics` +- `vcard qr code generator` + +### Empfehlung + +1. Deutsche, lokalisierte Toolseiten für `QR-Code-Generator`, `dynamischer QR-Code`, `QR-Code-Tracking`, `QR-Code-Scanner` und `QR-Code-Visitenkarte` priorisieren. +2. Die US-Startseite nicht primär über Barcode- und Wettbewerberbegriffe wachsen lassen; stattdessen klare englische Landingpages für `qr code generator`, `dynamic qr code generator`, `qr code tracking`, `vcard qr code generator` und `bulk qr code generator` stärken. +3. Jede Toolseite mit direkter Definition, Use Cases, Funktionsvergleich statisch/dynamisch, Tracking-Erklärung, FAQ und starken internen Links ausstatten. +4. Die bereits auffälligen `/alternatives/bitly`- und `/alternatives/flowcode`-Seiten zu belastbaren Vergleichsseiten mit echten Produktunterschieden ausbauen. + +## 2. GreenLens Pro + +### USA / Englisch + +GreenLens rankt bereits für ein relevantes Pflanzenfoto-/Identifikationsthema, überwiegend über eine Seite: + +- `google lens plant identification app` – Volumen 8.100, Position 32, `/plant-identifier-app` +- `identify a plant by picture` – 8.100, Position 79, `/identify-plant-photo` +- `identify plant from photo` – 8.100, Position 80 +- `identify plants by picture` – 8.100, Position 55 +- `plant id from photo` – 8.100, Position 55 +- `plant identifier with photo` – 8.100, Position 51 +- `flower picture identifier` – 1.300, Position 74 +- `what plant is this by picture` – 1.000, Position 93 +- `plant finder by photo` – 590, Position 58 + +### Wichtigste Wettbewerber + +picturethisai.com, plantnet.org, plant.id, plantsnap.com, apple.com, myplantin.com, lensapp.io sowie Google, YouTube und Reddit als SERP-/Marken-Ökosystem. + +### Keyword-Gaps / Chancen + +Die Wettbewerber decken unter anderem ab: + +- `plant identification`, `plant identifier`, `plant id` +- `what type of plant is this` +- `flower identifier by picture` +- `plant disease identifier` +- konkrete Pflanzen- und Symptombegriffe + +Die Domain-Intersection-Daten enthalten außerdem viele botanische Informationsbegriffe. Diese sollten nicht ungefiltert als SEO-Ziele übernommen werden: Für GreenLens sind Identifikation, Diagnose und nächste Pflegeschritte wertvoller als reine Pflanzenlexikon-Queries. + +### Empfehlung + +1. `/identify-plant-photo` als zentrale Money-/Tool-Seite auf Positionen 1–20 entwickeln: klare Antwort, Upload-/Scan-Nutzen, Beispiele, FAQ, App-CTA. +2. Separat clusterbare Seiten für `plant identifier`, `flower identifier`, `plant disease identifier`, `brown leaves`, `yellow leaves`, `overwatering` und `root rot` aufbauen. +3. Jede Diagnose-Seite muss sichtbar den nächsten Handlungsschritt erklären; nicht nur Pflanzenwissen liefern. +4. Interne Links zwischen Identifikation → Diagnose → Pflegeplan → App setzen. +5. Google-Lens-Vergleich als Trust-/Alternative-Seite nutzen, aber nicht die gesamte Informationsarchitektur auf Wettbewerberbegriffe stützen. + +## 3. Entscheidomat + +### Deutschland / Deutsch + +DataForSEO meldet aktuell **keine Ranked Keywords** für `entscheidomat.com` im deutschen Google-Markt. Das bedeutet nicht automatisch, dass die Website technisch nicht indexiert ist; es bedeutet, dass DataForSEO in diesem Markt keine verwertbaren Ranking-Keywords geliefert hat. + +### Wettbewerbs- und Gap-Signale + +Vergleichsdaten mit wheelofnames.com, random.org und zufallsgenerator.de zeigen relevante Suchthemen: + +- `glücksrad` – Volumen 246.000 +- `zufallsgenerator` – 165.000 +- `würfel` – 90.500 +- `google drehscheibe` – 40.500 +- `wheel of names` – 33.100 +- `spin the wheel` – 33.100 +- `coin flip` – 40.500, englischer/Internationaler Suchbegriff + +Ein Teil der Daten von random.org ist für Entscheidomat nicht passend, zum Beispiel Passwortgenerator- und englische Random-Number-Begriffe. Diese wurden als Kontamination verworfen. + +### Empfehlung + +1. Jede der sieben Funktionen als eigenständige, crawlbare SEO-Landingpage führen: `glücksrad`, `zufallszahl-generator`, `würfel-online`, `münze-werfen`, `ja-nein-generator`, `namen-auslosen`, `magic-8-ball`. +2. Pro Seite einen sichtbaren Definition-Block direkt unter dem H1 ergänzen. +3. Suchintention und Tool direkt verbinden: sofort nutzbares Tool plus Erklärung, Beispiele, FAQ und interne Links. +4. Die Startseite auf `Zufallsgenerator` und `Entscheidungshilfe` fokussieren; nicht alle sieben Begriffe gleich stark in Title/H1 stapeln. +5. Für `glücksrad`, `zufallsgenerator` und `würfel online` zuerst spezifische SEO- und UX-Landingpages optimieren, weil dort die größte erkennbare Nachfrage liegt. + +## Priorisierte Maßnahmen über alle drei Projekte + +### Priorität 1 – sofort + +- QRMaster: englische und deutsche Kern-Toolseiten auf `qr code generator`, `dynamic qr code`, `qr code tracking` und `QR-Code erstellen` ausrichten. +- GreenLens: `identify-plant-photo` als zentrale Conversion-/SEO-Seite ausbauen. +- Entscheidomat: sieben Tools als eindeutige SEO-Seiten mit sichtbarem HTML-Content und sauberem internen Linking absichern. + +### Priorität 2 – danach + +- Keyword-Mapping erstellen, damit pro Suchintention genau eine kanonische Seite ranken soll. +- Titles, H1s, Meta-Descriptions und FAQ-Blöcke auf die DataForSEO-Gaps ausrichten. +- Vergleichsseiten und Use Cases nur dort ausbauen, wo sie einen echten Nutzwert und interne Conversion-Verbindung haben. + +### Priorität 3 – Monitoring + +- Nach den Änderungen monatlich dieselben DataForSEO-Abfragen wiederholen. +- Zusätzlich Google Search Console je Domain auswerten; insbesondere bei Entscheidomat ist die Nullmessung ohne GSC nicht ausreichend. +- Rankings nicht isoliert bewerten: URL, Suchintention, Klicks, Impressions und Conversion gemeinsam messen. + +## Technischer Nachweis + +Die Live-Abfragen liefen mit HTTP 200 und DataForSEO-Task-Status 20000. Erfolgreich verarbeitet wurden: + +- 4 Ranked-Keyword-Abfragen +- 4 Competitor-Domain-Abfragen +- 12 Domain-Intersection-Abfragen für Wettbewerber-Gaps +- 4 Keyword-Metrik-Abfragen für Seed-Cluster + +Die Seed-Volume-Antworten wurden von der ersten Auswertung nicht in die Ergebnisliste übernommen, deshalb stammen die im Bericht genannten Volumina aus Ranked-Keyword- und Domain-Intersection-Daten. Die vier Seed-Requests selbst wurden technisch erfolgreich angenommen, werden aber nicht als separate Primärquelle für die genannten Zahlen verwendet. diff --git a/sql/2026-07-27_APPLY.sql b/sql/2026-07-27_APPLY.sql new file mode 100644 index 0000000..f1bf784 --- /dev/null +++ b/sql/2026-07-27_APPLY.sql @@ -0,0 +1,38 @@ +-- QR Master, Deploy 27.07.2026 - nur die Statements, die ausgefuehrt werden muessen. +-- Alle idempotent, ein zweiter Lauf schadet nicht. +-- Danach zwingend: npx prisma generate + +BEGIN; + +CREATE INDEX IF NOT EXISTS "QRCode_userId_type_status_idx" + ON "QRCode" ("userId", "type", "status"); + +ALTER TABLE "User" ADD COLUMN IF NOT EXISTS "limitReachedNudgeSentAt" TIMESTAMP(3); +ALTER TABLE "User" ADD COLUMN IF NOT EXISTS "firstScanNudgeSentAt" TIMESTAMP(3); + +CREATE INDEX IF NOT EXISTS "User_firstScanAt_firstScanNudgeSentAt_idx" + ON "User" ("firstScanAt", "firstScanNudgeSentAt"); + +-- Schuetzt Bestandsnutzer: ohne diese Zeile geht die "erster Scan"-Mail beim +-- ersten Cron-Lauf an jeden Nutzer mit Scan-Historie. +UPDATE "User" +SET "firstScanNudgeSentAt" = now() +WHERE "firstScanAt" IS NOT NULL + AND "firstScanAt" < now() - interval '7 days'; + +CREATE TABLE IF NOT EXISTS "QRDesignPreset" ( + "id" TEXT PRIMARY KEY, + "userId" TEXT NOT NULL REFERENCES "User"("id") ON DELETE CASCADE, + "name" TEXT NOT NULL, + "style" JSONB NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT now(), + "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT now() +); + +CREATE INDEX IF NOT EXISTS "QRDesignPreset_userId_idx" + ON "QRDesignPreset" ("userId"); + +CREATE UNIQUE INDEX IF NOT EXISTS "QRDesignPreset_userId_name_key" + ON "QRDesignPreset" ("userId", "name"); + +COMMIT; diff --git a/sql/2026-07-27_cro_retention_design.txt b/sql/2026-07-27_cro_retention_design.txt new file mode 100644 index 0000000..854a851 --- /dev/null +++ b/sql/2026-07-27_cro_retention_design.txt @@ -0,0 +1,280 @@ +================================================================================ +QR MASTER - SQL-BEFEHLE ZUM UMSETZUNGSPLAN VOM 27.07.2026 +Gehoert zu: PLAN_CRO_UND_RETENTION_2026-07-27.md +================================================================================ + +POLICY (aus CLAUDE.md): Keine Prisma-Migrationen. Alle Schemaaenderungen werden +als rohes SQL direkt gegen die laufende PostgreSQL-Instanz ausgefuehrt. Danach +prisma/schema.prisma von Hand angleichen und "npx prisma generate" laufen +lassen - niemals "npx prisma migrate". + +AUSFUEHREN ueber: + npm run docker:db +oder einzeln: + docker-compose exec db psql -U postgres -d qrmaster -c "" + +REIHENFOLGE: Block 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6. Alle Bloecke sind Pflicht. +Block 5 (prisma generate) darf nicht vergessen werden. + + +================================================================================ +BLOCK 0 - VORHER PRUEFEN (liest nur, aendert nichts) +================================================================================ + +-- 0.1 Wie viele FREE-Nutzer bekommen durch die Umstellung auf "nur ACTIVE +-- zaehlen" rueckwirkend Slots frei? Das ist eine Lockerung, nimmt also +-- niemandem etwas weg - aber die Zahl sollte man kennen. +SELECT COUNT(DISTINCT u.id) AS betroffene_free_nutzer +FROM "User" u +JOIN "QRCode" q ON q."userId" = u.id +WHERE u.plan = 'FREE' + AND q.type = 'DYNAMIC' + AND q.status = 'PAUSED'; + +-- 0.2 Wie viele Nutzer wuerden die neue "erster Scan"-Mail beim ersten +-- Cron-Lauf bekommen? WICHTIG: ohne Block 3.2 ginge sie an ALLE +-- Bestandsnutzer mit Scan-Historie, auch an solche, deren erster Scan +-- Monate zurueckliegt. Das waere kein Anlass mehr, sondern eine +-- Massenmail unter deinem Namen. +SELECT COUNT(*) AS wuerden_mail_bekommen +FROM "User" +WHERE "firstScanAt" IS NOT NULL; + +-- 0.3 Verteilung der Plaene - Kontext fuer alles Weitere. +SELECT plan, COUNT(*) AS nutzer +FROM "User" +GROUP BY plan +ORDER BY nutzer DESC; + +-- 0.4 Wie viele FREE-Nutzer sitzen aktuell am Limit? Das ist die Zielgruppe +-- des neuen Limit-Modals aus Phase 1 und der Limit-Mail aus Phase 5.1. +SELECT COUNT(*) AS free_nutzer_am_limit +FROM ( + SELECT u.id + FROM "User" u + JOIN "QRCode" q ON q."userId" = u.id + WHERE u.plan = 'FREE' AND q.type = 'DYNAMIC' AND q.status = 'ACTIVE' + GROUP BY u.id + HAVING COUNT(q.id) >= 3 +) t; + + +================================================================================ +BLOCK 1 - INDEX FUER DIE NEUE LIMIT-QUERY (Phase 1.1) +================================================================================ + +-- Die Zaehl-Query in src/app/(main)/api/qrs/route.ts bekommt zusaetzlich +-- status = 'ACTIVE'. Dieser Index deckt die neue Bedingung ab. +-- Dieselbe Aenderung gilt fuer src/app/(main)/api/user/stats/route.ts. + +CREATE INDEX IF NOT EXISTS "QRCode_userId_type_status_idx" + ON "QRCode" ("userId", "type", "status"); + + +================================================================================ +BLOCK 2 - MARKER-SPALTEN FUER DIE NEUEN RETENTION-MAILS (Phase 5) +================================================================================ + +-- limitReachedNudgeSentAt: Marker fuer die verhaltensbasierte Limit-Mail. +-- Ersetzt die kalenderbasierte Tag-7-Mail, die heute auch an Nutzer geht, +-- die das Limit gar nicht erreicht haben. +-- firstScanNudgeSentAt: Marker fuer die neue "erster Scan"-Mail. +-- Die Erkennung selbst braucht nichts Neues - User."firstScanAt" existiert +-- bereits und wird in src/app/(main)/r/[slug]/route.ts gesetzt. + +ALTER TABLE "User" ADD COLUMN IF NOT EXISTS "limitReachedNudgeSentAt" TIMESTAMP(3); +ALTER TABLE "User" ADD COLUMN IF NOT EXISTS "firstScanNudgeSentAt" TIMESTAMP(3); + +-- Index fuer den Cron-Job, der Nutzer mit erstem Scan ohne Versandmarker sucht. +CREATE INDEX IF NOT EXISTS "User_firstScanAt_firstScanNudgeSentAt_idx" + ON "User" ("firstScanAt", "firstScanNudgeSentAt"); + + +================================================================================ +BLOCK 3 - BESTANDSDATEN VORBEREITEN (unbedingt VOR dem ersten Cron-Lauf) +================================================================================ + +-- 3.1 Nutzer, die schon am Limit sitzen, haben die Limit-Mail nie bekommen +-- koennen - es gab sie nicht. Ob sie sie nachtraeglich bekommen sollen, +-- ist eine Entscheidung: +-- +-- Variante A - sie sollen die Mail bekommen: dieses Statement NICHT +-- ausfuehren. Der erste Cron-Lauf schickt sie an alle, die am Limit sind. +-- Bei vielen Bestandsnutzern ist das ein Versand-Peak. +-- +-- Variante B - nur Neufaelle ab jetzt: Statement ausfuehren, dann bekommen +-- bestehende Limit-Faelle keine Mail und die Sequenz startet sauber. + +-- Variante B (auskommentiert - bewusst entscheiden und dann aktivieren): +-- UPDATE "User" u +-- SET "limitReachedNudgeSentAt" = now() +-- WHERE u.plan = 'FREE' +-- AND (SELECT COUNT(*) FROM "QRCode" q +-- WHERE q."userId" = u.id AND q.type = 'DYNAMIC' AND q.status = 'ACTIVE') >= 3; + +-- 3.2 PFLICHT: Bestandsnutzer, deren erster Scan laenger als 7 Tage her ist, +-- als "bereits benachrichtigt" markieren. Ohne dieses Statement geht die +-- "erster Scan"-Mail beim ersten Lauf an die gesamte Bestandsbasis - mit +-- einem Anlass, der Monate zurueckliegt. +UPDATE "User" +SET "firstScanNudgeSentAt" = now() +WHERE "firstScanAt" IS NOT NULL + AND "firstScanAt" < now() - interval '7 days'; + +-- 3.3 Kontrolle nach 3.2 - sollte eine kleine, plausible Zahl sein. +SELECT COUNT(*) AS offene_erster_scan_mails +FROM "User" +WHERE "firstScanAt" IS NOT NULL + AND "firstScanNudgeSentAt" IS NULL; + + +================================================================================ +BLOCK 4 - PFLICHT: DESIGN-VORLAGEN +================================================================================ + +-- Nicht mehr optional: die Design-Presets sind gebaut. Ohne diese Tabelle +-- laufen GET/POST/DELETE /api/design-presets und die Preset-Auswahl im +-- Bulk-Flow in einen Prisma-Fehler. +-- +-- Die Formen selbst brauchen weiterhin keine Schemaaenderung: QRCode."style" +-- ist JSON, moduleShape, eyeFrameShape, eyeBallShape, gradientMode und +-- gradientTo liegen dort ohne Migration drin. + +CREATE TABLE IF NOT EXISTS "QRDesignPreset" ( + "id" TEXT PRIMARY KEY, + "userId" TEXT NOT NULL REFERENCES "User"("id") ON DELETE CASCADE, + "name" TEXT NOT NULL, + "style" JSONB NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT now(), + "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT now() +); + +CREATE INDEX IF NOT EXISTS "QRDesignPreset_userId_idx" + ON "QRDesignPreset" ("userId"); + +CREATE UNIQUE INDEX IF NOT EXISTS "QRDesignPreset_userId_name_key" + ON "QRDesignPreset" ("userId", "name"); + + +================================================================================ +BLOCK 5 - PRISMA-SCHEMA VON HAND ANGLEICHEN (kein SQL, aber Pflichtschritt) +================================================================================ + +In prisma/schema.prisma, model User, im Block "// Retention email tracking" +ergaenzen: + + limitReachedNudgeSentAt DateTime? + firstScanNudgeSentAt DateTime? + +In model QRCode ergaenzen: + + @@index([userId, type, status]) + +Ausserdem (Block 4 ist Pflicht) - beides ist im Repo bereits eingetragen, +diese Angabe dient nur der Kontrolle: + + model QRDesignPreset { + id String @id @default(cuid()) + userId String + name String + style Json + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + + @@unique([userId, name]) + @@index([userId]) + } + +und in model User die Gegenseite: + + designPresets QRDesignPreset[] + +Danach: + + npx prisma generate + +NICHT "npx prisma migrate" - das wuerde gegen die Policy in CLAUDE.md verstossen. + + +================================================================================ +BLOCK 6 - VERIFIKATION NACH DEM DEPLOY +================================================================================ + +-- 6.1 Sind alle neuen Spalten da? +SELECT column_name, data_type +FROM information_schema.columns +WHERE table_name = 'User' + AND column_name IN ('limitReachedNudgeSentAt', 'firstScanNudgeSentAt', + 'activationNudgeSentAt', 'upgradeNudgeSentAt', + 'thirtyDayNudgeSentAt', 'firstScanAt') +ORDER BY column_name; + +-- 6.2 Sind alle neuen Indizes da? +SELECT indexname +FROM pg_indexes +WHERE tablename IN ('User', 'QRCode', 'QRDesignPreset') + AND indexname IN ('QRCode_userId_type_status_idx', + 'User_firstScanAt_firstScanNudgeSentAt_idx', + 'QRDesignPreset_userId_idx', + 'QRDesignPreset_userId_name_key') +ORDER BY indexname; + +-- 6.3 Nutzt die neue Limit-Query den Index? Sollte "Index Scan" oder +-- "Index Only Scan" zeigen, keinen "Seq Scan". +EXPLAIN ANALYZE +SELECT COUNT(*) FROM "QRCode" +WHERE "userId" = (SELECT id FROM "User" LIMIT 1) + AND type = 'DYNAMIC' + AND status = 'ACTIVE'; + +-- 6.4 Wie viele Mails stehen im naechsten Cron-Lauf an? Vor dem ersten +-- scharfen Lauf pruefen, damit es keine Ueberraschung gibt. +SELECT + (SELECT COUNT(*) FROM "User" + WHERE "firstScanAt" IS NOT NULL AND "firstScanNudgeSentAt" IS NULL) + AS erster_scan_mails, + (SELECT COUNT(*) FROM "User" u WHERE u.plan = 'FREE' + AND u."limitReachedNudgeSentAt" IS NULL + AND (SELECT COUNT(*) FROM "QRCode" q + WHERE q."userId" = u.id AND q.type = 'DYNAMIC' AND q.status = 'ACTIVE') >= 3) + AS limit_mails, + (SELECT COUNT(*) FROM "User" + WHERE "activationNudgeSentAt" IS NULL + AND "createdAt" < now() - interval '3 days') + AS aktivierungs_mails; + + +================================================================================ +ROLLBACK - falls etwas zurueckgedreht werden muss +================================================================================ + +-- Die Spalten sind additiv und nullable, ein Rollback ist normalerweise nicht +-- noetig. Falls doch: Datenverlust bei den Versandmarkern beachten - danach +-- koennten Nutzer Mails ein zweites Mal bekommen. + +-- ALTER TABLE "User" DROP COLUMN IF EXISTS "limitReachedNudgeSentAt"; +-- ALTER TABLE "User" DROP COLUMN IF EXISTS "firstScanNudgeSentAt"; +-- DROP INDEX IF EXISTS "User_firstScanAt_firstScanNudgeSentAt_idx"; +-- DROP INDEX IF EXISTS "QRCode_userId_type_status_idx"; +-- DROP TABLE IF EXISTS "QRDesignPreset"; + + +================================================================================ +ZUSAMMENFASSUNG +================================================================================ + +Pflicht: 2 Spalten, 2 Indizes, 1 UPDATE fuer Bestandsdaten (Block 3.2) +Pflicht: 1 Tabelle mit 2 Indizes (Design-Presets, Block 4) +Formen: brauchen kein SQL - QRCode."style" ist bereits JSON +Phasen 1-4: brauchen kein SQL ausser dem Index aus Block 1 + +NACH dem SQL zwingend: npx prisma generate +Ohne generate kennt der Prisma-Client das Modell QRDesignPreset nicht und +/api/design-presets wirft zur Laufzeit. + +Der einzige Schritt mit echtem Risiko ist Block 3.2. Wird er vergessen, geht +die "erster Scan"-Mail an die gesamte Bestandsbasis. + +================================================================================ diff --git a/src/app/(main)/(app)/AppLayout.tsx b/src/app/(main)/(app)/AppLayout.tsx index e54f07b..701f8ed 100644 --- a/src/app/(main)/(app)/AppLayout.tsx +++ b/src/app/(main)/(app)/AppLayout.tsx @@ -130,7 +130,7 @@ export default function AppLayout({ }, { name: t('nav.pricing'), - href: '/pricing', + href: '/upgrade', icon: ( @@ -164,11 +164,11 @@ export default function AppLayout({ className={`fixed top-0 left-0 z-50 h-full w-64 bg-white border-r border-gray-200 transform transition-transform lg:translate-x-0 ${sidebarOpen ? 'translate-x-0' : '-translate-x-full' }`} > -
- - QR Master - QR Master - +
+ + QR Master + QR Master + -
- {/* User Menu */} - -
- - {getUserInitials()} - -
- - {getDisplayName()} - - - - - +
+ {/* User Menu */} + +
+ + {getUserInitials()} + +
+ + {getDisplayName()} + + + + + } > @@ -242,13 +242,13 @@ export default function AppLayout({ {/* Page content */} -
- {children} -
+
+ {children} +
{/* Footer */}
); -} +} diff --git a/src/app/(main)/(app)/bulk-creation/page.tsx b/src/app/(main)/(app)/bulk-creation/page.tsx index b1b97c2..b71687a 100644 --- a/src/app/(main)/(app)/bulk-creation/page.tsx +++ b/src/app/(main)/(app)/bulk-creation/page.tsx @@ -1,6 +1,7 @@ 'use client'; import React, { useState, useCallback } from 'react'; +import Link from 'next/link'; import { useDropzone } from 'react-dropzone'; import Papa from 'papaparse'; import ExcelJS from 'exceljs'; @@ -8,7 +9,8 @@ import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/Card'; import { Button } from '@/components/ui/Button'; import { Badge } from '@/components/ui/Badge'; import { Select } from '@/components/ui/Select'; -import { QRCodeSVG } from 'qrcode.react'; +import { QRCodeSVG } from 'qrcode.react'; +import { renderStyledQRSvg } from '@/lib/render-qr-svg'; import { showToast } from '@/components/ui/Toast'; import { useTranslation } from '@/hooks/useTranslation'; import { useCsrf } from '@/hooks/useCsrf'; @@ -39,6 +41,38 @@ export default function BulkCreationPage() { const [userPlan, setUserPlan] = useState('FREE'); const [isDynamic, setIsDynamic] = useState(false); const [remainingDynamic, setRemainingDynamic] = useState(0); + // Rows the API refused. Previously these vanished silently and the success + // toast reported a smaller number with no explanation - the worst kind of + // failure for someone who is about to send a batch to print. + const [failedRows, setFailedRows] = useState<{ row: number; title: string; reason: string }[]>([]); + // A saved design applied to the whole batch. This is the reason presets exist: + // 500 codes that all look like the same client, from one upload. + const [presets, setPresets] = useState<{ id: string; name: string; style: any }[]>([]); + const [presetId, setPresetId] = useState(''); + + // Reload the remaining dynamic quota from the server. Counting down locally + // drifts as soon as anything is created in another tab, which is how rows + // ended up being refused mid-batch in the first place. + const refreshQuota = async () => { + try { + const statsRes = await fetch('/api/user/stats'); + if (statsRes.ok) { + const stats = await statsRes.json(); + setRemainingDynamic((stats.dynamicLimit || 0) - (stats.dynamicUsed || 0)); + } + } catch (error) { + console.error('Error refreshing quota:', error); + } + }; + + React.useEffect(() => { + fetch('/api/design-presets') + .then((r) => (r.ok ? r.json() : [])) + .then((d) => Array.isArray(d) && setPresets(d)) + .catch(() => {}); + }, []); + + const activeStyle = () => presets.find((p) => p.id === presetId)?.style ?? null; // Check user plan and dynamic quota on mount React.useEffect(() => { @@ -177,15 +211,15 @@ export default function BulkCreationPage() { // Use qrcode library to generate SVG const QRCode = require('qrcode'); - const qrSvg = await QRCode.toString(content, { - type: 'svg', - width: 300, - margin: 2, - color: { - dark: '#000000', - light: '#FFFFFF', - }, - }); + const style = activeStyle(); + const qrSvg = style + ? renderStyledQRSvg(String(content), style, 300) + : await QRCode.toString(content, { + type: 'svg', + width: 300, + margin: 2, + color: { dark: '#000000', light: '#FFFFFF' }, + }); qrCodes.push({ title: String(title), @@ -212,20 +246,35 @@ export default function BulkCreationPage() { const toProcess = remainingDynamic > 0 ? data.slice(0, remainingDynamic) : []; if (toProcess.length === 0) { - showToast('Du hast keine dynamischen QR-Codes mehr übrig. Bitte upgrade deinen Plan.', 'error'); + showToast('No dynamic QR codes left on your plan. Free a slot or upgrade to continue.', 'error'); setLoading(false); return; } if (data.length > remainingDynamic) { - showToast(`Nur ${remainingDynamic} dynamische Codes verfügbar. Es werden nur die ersten ${remainingDynamic} Zeilen verarbeitet.`, 'warning'); + showToast( + `Only ${remainingDynamic} dynamic codes left. The first ${remainingDynamic} rows will be processed - the rest are listed after the run.`, + 'warning' + ); } try { const QRCode = require('qrcode'); const results: GeneratedQR[] = []; + const failures: { row: number; title: string; reason: string }[] = []; - for (const row of toProcess) { + // Rows the plan could not cover are counted from the start, so the summary + // reflects the whole upload and not just the slice we attempted. + data.slice(toProcess.length).forEach((row, i) => { + failures.push({ + row: toProcess.length + i + 1, + title: String(row[mapping.title as keyof typeof row] || 'Untitled'), + reason: 'No dynamic code slots left on your plan', + }); + }); + + for (let i = 0; i < toProcess.length; i++) { + const row = toProcess[i]; const title = String(row[mapping.title as keyof typeof row] || 'Untitled'); const url = String(row[mapping.content as keyof typeof row] || 'https://example.com'); @@ -242,23 +291,61 @@ export default function BulkCreationPage() { if (res.ok) { const qr = await res.json(); const redirectUrl = `${window.location.origin}/r/${qr.slug}`; - const svg = await QRCode.toString(redirectUrl, { type: 'svg', width: 300, margin: 2 }); + const style = activeStyle(); + const svg = style + ? renderStyledQRSvg(redirectUrl, style, 300) + : await QRCode.toString(redirectUrl, { type: 'svg', width: 300, margin: 2 }); results.push({ title, content: url, svg, slug: qr.slug, redirectUrl }); + } else { + const err = await res.json().catch(() => null); + failures.push({ + row: i + 1, + title, + reason: err?.error === 'Limit reached' + ? 'No dynamic code slots left on your plan' + : err?.error || `Request failed (${res.status})`, + }); } } setGeneratedQRs(results); - setRemainingDynamic(prev => Math.max(0, prev - results.length)); + setFailedRows(failures); + await refreshQuota(); setStep('complete'); - showToast(`${results.length} dynamische QR-Codes erstellt!`, 'success'); + + if (failures.length > 0) { + showToast( + `${results.length} of ${data.length} codes created. ${failures.length} row${failures.length === 1 ? '' : 's'} could not be added - see the list below.`, + 'warning' + ); + } else { + showToast(`${results.length} dynamic QR codes created.`, 'success'); + } } catch (error) { console.error('Dynamic QR generation error:', error); - showToast('Fehler beim Erstellen der dynamischen QR-Codes', 'error'); + showToast('Something went wrong while creating the dynamic QR codes.', 'error'); } finally { setLoading(false); } }; + // Hands the user back exactly the rows that did not make it, in a format they + // can re-upload once they have room. Telling someone what is missing without + // giving them the list is only half an apology. + const downloadFailedRowsCsv = () => { + const header = 'row,title,reason\n'; + const body = failedRows + .map(f => `${f.row},"${f.title.replace(/"/g, '""')}","${f.reason.replace(/"/g, '""')}"`) + .join('\n'); + const blob = new Blob([header + body], { type: 'text/csv;charset=utf-8;' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = 'qrmaster-missing-rows.csv'; + a.click(); + URL.revokeObjectURL(url); + }; + const downloadAllQRCodes = async () => { const zip = new JSZip(); @@ -370,7 +457,7 @@ export default function BulkCreationPage() { -
@@ -386,6 +473,26 @@ export default function BulkCreationPage() {

{t('bulk.title')}

{t('bulk.subtitle')}

+ {/* Apply a saved design to the whole batch. */} + {presets.length > 0 && ( +
+ +

Only URL-capable formats available. EAN-13, UPC, and ITF-14 encode numbers only and cannot embed a redirect URL. @@ -834,13 +1031,13 @@ export default function CreatePage() { onChange={(e) => setContent({ ...content, format: e.target.value })} className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary-500" > - - - - - - - + + + + + + +

@@ -963,25 +1160,214 @@ export default function CreatePage() {
{t('create.style')} - {!canCustomizeColors && ( - PRO Feature - )} + Free on every plan
- {!canCustomizeColors && ( -
-

- Upgrade to PRO to customize colors, add logos, and brand your QR codes. -

- - - -
- )} + {/* Module shape. Colors are free; shapes are the Pro driver that + replaced them. Locked options stay clickable so the preview + shows what is being bought before anyone pays for it. */} +
+
+ + {!canUseShapes && Pro} +
+
+ {([...PRO_MODULE_SHAPES, ...BUSINESS_MODULE_SHAPES] as ModuleShape[]).map((shape) => { + const isBusinessOnly = BUSINESS_MODULE_SHAPES.includes(shape); + const allowed = shape === 'square' + || (isBusinessOnly ? canUseFullDesign : canUseShapes); + return ( + + ); + })} +
+
+ + {/* Eye styles. Only the combinations that survived decoding are + offered - see the note in lib/qr-shapes.ts. */} +
+ { + if (!canUseShapes) { + setUpgradeReason('shapes'); + setUpgradeOpen(true); + return; + } + setEyeBallShape(e.target.value as EyeBallShape); + }} + options={Object.entries(EYE_BALL_LABELS).map(([value, label]) => ({ + value, + label, + }))} + /> +
+ + {/* Gradient. Business only - the renderer takes it as a prop, so + this is purely a gating and input concern. */} +
+
+ + {!canUseFullDesign && Business} +
+
+ {(['none', 'linear', 'radial'] as const).map((mode) => ( + + ))} +
+ {gradientMode !== 'none' && ( +
+ + setGradientTo(e.target.value)} + className="h-10 w-12 rounded border border-gray-300" + /> + setGradientTo(e.target.value)} + className="flex-1" + /> +
+ )} +
+ + {/* Scannability. Says what was changed and why, rather than + silently raising the error correction behind the user. */} + {(LOW_COVERAGE_SHAPES.includes(moduleShape) || logoUrl) && ( +
+

+ {logoUrl + ? 'Error correction is set to H because this code carries a logo.' + : `"${MODULE_SHAPE_LABELS[moduleShape]}" fills less of each module, so error correction has been raised.`} +

+

+ Print it at 2 x 2 cm or larger, and scan it once with your own + phone before you send it to the printer. +

+
+ )} + + {/* Saved presets. Business only. Repeatability is the actual + product here - the star shape is not what an agency buys. */} + {canUseFullDesign && ( +
+ + {presets.length > 0 && ( +
+ {presets.map((preset) => ( + + + + + ))} +
+ )} +
+ setPresetName(e.target.value)} + placeholder="Client A" + className="flex-1" + /> + +
+

+ Saving under an existing name overwrites it. +

+
+ )} + {/* Frame Options */}
@@ -1004,7 +1390,7 @@ export default function CreatePage() {
- +
- +
- +