Files
QR-master/.hermes/plans/2026-07-13_151727-qr-master-decision-content-and-market-proof.md
2026-07-13 18:51:52 +02:00

220 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# QR Master: Decision-Content + Market-Proof Implementation Plan
> **For Hermes:** Execute only after Timo explicitly asks to implement. Do not create a page cluster before the hub has real search/conversion signals.
**Goal:** Ship one German decision page for the *static vs. dynamic QR code* decision, instrument it with existing analytics, then test the exact message with real DACH restaurants/cafés before expanding SEO content.
**Architecture:** Reuse the existing localized, data-driven use-case route `src/app/de/[slug]/page.tsx` and `UseCasePageTemplate`. Add one German content object to `src/lib/growth-pages-de.ts`; the route already creates static params, self-canonical metadata, hreflang pairs, Breadcrumb/FAQ schema and CTA tracking. Do not touch the English restaurant page: it already owns the restaurant-menu intent at `/restaurants`, and the old English use-case route redirects there.
**Tech Stack:** Next.js App Router, TypeScript, existing `UseCasePageTemplate`, PostHog (`MarketingPageTracker` / `TrackedCtaLink`), npm.
---
## Current repo facts
- German localized use-cases are generated from `src/lib/growth-pages-de.ts:29` through `src/app/de/[slug]/page.tsx:14-108`.
- The route gives each item a self-canonical and creates static params from the data object (`src/app/de/[slug]/page.tsx:14-38`).
- The existing template already tracks page views as `landing_page_viewed` and CTA clicks as `cta_clicked` (`src/components/marketing/MarketingAnalytics.tsx:28-93`). Do **not** create parallel events until the funnels actual setup/signup events are located.
- `/use-cases/restaurant-menu-qr-codes` is a permanent redirect to `/restaurants` (`next.config.mjs:89-92`). The `/restaurants` page already owns English menu/PDF/reprint copy (`src/app/(main)/(marketing)/restaurants/page.tsx:34-69`).
- No German restaurant/speisekarte page exists in `src/lib/growth-pages-de.ts` today.
## Non-goals
- No ten-page pSEO rollout.
- No bespoke template, calculator, schema type, A/B framework, or new tracking architecture.
- No claim of guaranteed savings, GDPR compliance, or “instant” changes unless product behaviour and legal wording are verified.
- No customer-story or dashboard screenshot presented as proof until it is real.
---
### Task 1: Lock the positioning and page boundary
**Objective:** Ensure this page wins a new decision query instead of competing with generic generator or restaurant-menu pages.
**Files:**
- No code change.
- Review: `src/app/(marketing-de)/qr-code-erstellen/page.tsx:26-87`
- Review: `src/app/(main)/(marketing)/restaurants/page.tsx:34-170`
- Review: `next.config.mjs:63-97`
**Step 1: Adopt the exact target user and job**
- Segment: DACH restaurant/café operators with printed table tents, menus, takeaway flyers, or window signs.
- Job: Decide *before printing* whether a QR destination needs to stay editable.
- Primary query family: `statischer oder dynamischer qr code`, `unterschied statischer dynamischer qr code`, `qr code link später ändern`.
- Explicit exclusion: do not target the generic “free QR generator” query or try to become a restaurant POS/menu-builder page.
**Step 2: Define the content angle**
Use this hero content:
- H1: `Statischer oder dynamischer QR-Code? Entscheide vor dem Druck.`
- Intro: `Wenn sich dein Link, Menü, PDF oder Angebot später ändern könnte, brauchst du einen QR-Code, dessen Ziel du ohne Neudruck aktualisieren kannst.`
- Primary CTA: `Dynamischen QR-Code erstellen`
- Secondary CTA: `Zum QR-Code-Generator`
**Step 3: Define the one-sentence decision rule**
`Bleibt das Ziel garantiert unverändert, reicht ein statischer QR-Code. Kann sich Ziel, PDF, Menü, Aktion oder Platzierung ändern, ist ein dynamischer QR-Code die sichere Wahl vor dem Druck.`
**Acceptance criteria:** The page is clearly a decision hub, not another restaurant-menu landing page; it contains the decision within the first viewport.
---
### Task 2: Add one localized use-case record
**Objective:** Publish exactly one data-backed German page at `/de/statischer-vs-dynamischer-qr-code` through the current route/template.
**Files:**
- Modify: `src/lib/growth-pages-de.ts` (inside `useCasePagesDe`, before the closing object)
**Step 1: Add the record shape**
Add a `UseCasePageContentDe` record with:
```ts
'statischer-vs-dynamischer-qr-code': {
enSlug: 'dynamic-qr-code-generator',
slug: 'statischer-vs-dynamischer-qr-code',
href: '/de/statischer-vs-dynamischer-qr-code',
title: 'Statischer oder dynamischer QR-Code?',
cluster: 'qr-code-basics',
parentHref: '/dynamic-qr-code-generator',
parentTitle: 'Dynamischer QR-Code-Generator',
ctaLabel: 'Dynamischen QR-Code erstellen',
eyebrow: 'Vor dem Druck entscheiden',
titleSuffix: 'vor dem Druck',
metaDescription: 'Statischer oder dynamischer QR-Code? Vergleiche Änderbarkeit, Druckrisiko und Tracking und entscheide vor Flyer, Speisekarte oder Tischaufsteller.',
// remaining template fields in the following steps
}
```
**Step 2: Write unique decision content—not token substitutions**
Populate the template fields with these content requirements:
- `answer`: the exact decision rule from Task 1.
- `whenToUse`: three observable conditions: destination cannot change; a PDF/menu/offer might change; scans must be measured by placement.
- `comparisonItems`: only concrete trade-offs, e.g. destination after print, response to a changed PDF, scan measurement. Validate the templates left/right presentation before wording the boolean values.
- `howToSteps`: create a dynamic code → print it once → change the destination later in the dashboard.
- `workflowCards`: one realistic café example (30 table tents, new menu PDF), one flyer/event example, one separate-placement tracking example.
- `checklist`: test print size/contrast, use a descriptive scan CTA, point to a mobile target, keep a dynamic target when it can change.
- `supportLinks`: `/dynamic-qr-code-generator`, `/qr-code-tracking`, `/reprint-calculator`, `/qr-code-print-size-guide` after verifying every target resolves.
- `faq`: 34 factual FAQs such as “Kann ich den Link eines statischen QR-Codes später ändern?” and “Wann lohnt sich ein dynamischer QR-Code für eine Speisekarte?”
**Step 3: Avoid fictional proof**
Set no `heroImage` unless a real product/dashboard or verified purpose-built illustration exists. If the template needs an image visually, use a clearly labelled product workflow asset—not a fake customer outcome or fabricated dashboard state.
**Acceptance criteria:** `generateStaticParams` includes the slug; the page has unique German title, description, H1, intro, FAQ and internal-link context.
---
### Task 3: Verify rendered SEO and conversion path
**Objective:** Confirm the new route is indexable, non-cannibalizing, and sends users into a working generator flow.
**Files:**
- Verify: `src/app/de/[slug]/page.tsx:18-52`
- Verify: `src/components/marketing/UseCasePageTemplate.tsx:440-526`
- Verify: `src/app/sitemap.ts`
**Step 1: Run static checks**
Run from repository root:
```bash
npm run lint
npm run build
```
Expected: both commands exit `0`.
**Step 2: Run the local smoke test**
Start the app with `npm run dev`, then inspect:
- `http://localhost:3050/de/statischer-vs-dynamischer-qr-code`
- page source/rendered HTML contains one H1
- canonical is `https://www.qrmaster.net/de/statischer-vs-dynamischer-qr-code`
- page has language alternates generated by `buildLanguageAlternates`
- primary CTA reaches the German setup/generator flow actually intended for conversion
- all related-resource URLs return a valid page (not redirects to irrelevant pages or 404)
- mobile: H1, decision rule, and primary CTA fit/appear before excessive scrolling; comparison is readable
**Step 3: Verify tracking rather than inventing event names**
Use the existing PostHog events first:
- `landing_page_viewed` with `landing_page_slug=/de/statischer-vs-dynamischer-qr-code`
- `cta_clicked` with `cta_location=hero_primary` and this use case slug
Before adding `qr_setup_started` or `signup_completed`, locate their real implementation. If no downstream events exist, add them only after documenting the actual generator/signup handoff and preserving no-PII tracking.
**Acceptance criteria:** build passes, canonical and CTA are correct, events appear in PostHog (or the tracking limitation is explicitly documented), and there is no new page aimed at `/restaurants` restaurant-menu keyword set.
---
### Task 4: Run a 7-day manual market test in parallel
**Objective:** Test whether the language describes a costly current problem, not merely whether people say they like the page.
**Files:**
- No product code required.
- Create a local working sheet only if Timo asks; do not automate outreach first.
**Step 1: Build a 20-prospect list (45 minutes max)**
Collect 20 independent restaurants/cafés in one local area. Criteria:
- visible printed menu/table-tent/window QR in Google photos, Instagram, or own site;
- a current menu PDF, ordering page, seasonal offer, or booking link;
- reachable email, Instagram, or contact form.
**Step 2: Send 10 short research-first messages**
Use this wording, adapted with the venues name and observed QR use:
> Hi [Name], kurze Frage ich schaue mir gerade an, wie Restaurants QR-Codes auf Tischaufstellern und Speisekarten nutzen. Musstet ihr den Link, die PDF-Speisekarte oder Preise nach dem Druck schon einmal ändern? Was habt ihr dann gemacht? Ich verkaufe dir gerade nichts; ich will den Ablauf verstehen.
Do not pitch QR Master in the first message.
**Step 3: Follow up only with a relevant offer**
If they mention an actual recent issue, reply:
> Danke, genau diesen Fall untersuche ich. Ich baue ein Setup, bei dem der gedruckte QR-Code bleibt und du nur das Ziel aktualisierst. Wenn du willst, richte ich dir den nächsten Code testweise ein und prüfe vorher kostenlos, ob euer aktueller Code überhaupt update-sicher ist.
**Step 4: Record proof, not compliments**
For every reply capture: last incident, workaround, print/time cost, current QR tool, decision-maker, and whether they agree to a test/pilot. Strong evidence is a real past case, a follow-up call, a current QR audit, or a pilot—not “klingt gut”.
**Acceptance criteria:** at least 10 contacts sent and one of these evidence types captured: concrete past incident, audit request, pilot, call, trial, or explicit rejection with reason.
---
### Task 5: Make the expansion/kill decision after 714 days
**Objective:** Prevent a content factory before a signal exists.
**Decision table:**
| Signal | Decision |
| --- | --- |
| Search impressions/query relevance + CTA clicks | Build exactly one follow-up: `/de/qr-code-nach-druck-aendern` focused on recovery intent. |
| At least 2 concrete restaurant incidents or 1 pilot | Improve the restaurant-specific proof/CTA or ship a German restaurant page only after title/canonical mapping against `/restaurants`. |
| No relevant queries, replies, CTA clicks, or incidents | Do not create more pages. Change segment/message (e.g. flyers/events/real-estate) and repeat outreach. |
**Do not expand to** flyer, business-card, event, packaging, PDF, and restaurant subpages simultaneously. One successful page/message earns one sibling.
---
## Final Definition of Done
1. One live, unique German decision page—not a page cluster.
2. `npm run lint` and `npm run build` pass.
3. Canonical, hreflang, CTA and tracking are verified on the rendered route.
4. Ten manual research contacts are sent.
5. A seven-day review contains real proof: Search Console query data, PostHog CTA data, replies, calls, audits, trials, or payments.
6. Only then decide whether `/de/qr-code-nach-druck-aendern` deserves implementation.