# 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 funnel’s 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 template’s 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`: 3–4 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 venue’s 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 7–14 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.