feat: Add marketing and use case pages, their data structures, and supporting UI components.

This commit is contained in:
Timo Knuth 2026-03-09 12:47:52 +01:00
parent f5f3979996
commit 3c8e6bd19f
22 changed files with 4047 additions and 184 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,48 +1,31 @@
# QR Master
> QR Master is a B2B SaaS platform for creating dynamic QR codes with real-time analytics, custom branding, and bulk generation. Free tools available for URL, WiFi, vCard, WhatsApp, Instagram, and 15+ other QR code types.
- Primary domain: https://www.qrmaster.net
- Free static QR codes, paid dynamic QR codes with tracking
- German landing page available at /qr-code-erstellen
- Enterprise features: Bulk generation, API access, team management
## Free Tools
- [URL QR Generator](https://www.qrmaster.net/tools/url-qr-code): Create QR codes for any website link
- [WiFi QR Generator](https://www.qrmaster.net/tools/wifi-qr-code): Share WiFi credentials via QR code
- [vCard QR Generator](https://www.qrmaster.net/tools/vcard-qr-code): Digital business card QR codes
- [Text QR Generator](https://www.qrmaster.net/tools/text-qr-code): Encode plain text in QR codes
- [Email QR Generator](https://www.qrmaster.net/tools/email-qr-code): Pre-filled email QR codes
- [SMS QR Generator](https://www.qrmaster.net/tools/sms-qr-code): Send SMS messages via QR
- [Phone QR Generator](https://www.qrmaster.net/tools/phone-qr-code): One-tap phone call QR codes
- [WhatsApp QR Generator](https://www.qrmaster.net/tools/whatsapp-qr-code): Start WhatsApp chats instantly
- [Instagram QR Generator](https://www.qrmaster.net/tools/instagram-qr-code): Grow Instagram followers
- [TikTok QR Generator](https://www.qrmaster.net/tools/tiktok-qr-code): Link to TikTok profiles
- [Twitter QR Generator](https://www.qrmaster.net/tools/twitter-qr-code): Share Twitter/X profiles
- [YouTube QR Generator](https://www.qrmaster.net/tools/youtube-qr-code): Link to videos and channels
- [Facebook QR Generator](https://www.qrmaster.net/tools/facebook-qr-code): Share Facebook pages
- [PayPal QR Generator](https://www.qrmaster.net/tools/paypal-qr-code): Accept PayPal payments
- [Crypto QR Generator](https://www.qrmaster.net/tools/crypto-qr-code): Bitcoin and crypto wallet QR codes
- [Event QR Generator](https://www.qrmaster.net/tools/event-qr-code): Calendar event QR codes
- [Geolocation QR Generator](https://www.qrmaster.net/tools/geolocation-qr-code): Share map locations
- [Zoom QR Generator](https://www.qrmaster.net/tools/zoom-qr-code): Join Zoom meetings instantly
- [Teams QR Generator](https://www.qrmaster.net/tools/teams-qr-code): Join Microsoft Teams meetings
## Premium Features
- [Dynamic QR Codes](https://www.qrmaster.net/dynamic-qr-code-generator): Editable QR codes with real-time tracking
- [Bulk QR Generator](https://www.qrmaster.net/bulk-qr-code-generator): Generate hundreds of QR codes from CSV/Excel
- [QR Code Tracking](https://www.qrmaster.net/qr-code-tracking): Analytics dashboard with scan statistics
## Information
- [Homepage](https://www.qrmaster.net): Main landing page
- [Pricing](https://www.qrmaster.net/pricing): Free, Pro, and Business plans
- [FAQ](https://www.qrmaster.net/faq): Frequently asked questions
- [Blog](https://www.qrmaster.net/blog): Tips and guides for QR code marketing
- [Privacy Policy](https://www.qrmaster.net/privacy): Data privacy information
## Localized Pages
- [German Landing Page](https://www.qrmaster.net/qr-code-erstellen): QR Code Generator auf Deutsch
# QR Master
> QR Master is a B2B SaaS platform for dynamic QR codes, scan analytics, bulk generation, and privacy-conscious campaign tracking.
- Primary domain: https://www.qrmaster.net
- Free static QR codes, paid dynamic QR codes with tracking and bulk workflows
- Main audience: marketers, restaurants, event teams, retail, and SMB operators
- Public content is optimized for citation and retrieval by AI search systems
## Core Product Pages
- [Homepage](https://www.qrmaster.net): Product overview and positioning for dynamic QR codes
- [Pricing](https://www.qrmaster.net/pricing): Plans, limits, and upgrade paths
- [Dynamic QR Code Generator](https://www.qrmaster.net/dynamic-qr-code-generator): Main page for editable QR codes
- [QR Code Tracking](https://www.qrmaster.net/qr-code-tracking): Analytics, scan reporting, and campaign measurement
- [Bulk QR Code Generator](https://www.qrmaster.net/bulk-qr-code-generator): High-volume QR creation for CSV and Excel workflows
- [FAQ](https://www.qrmaster.net/faq): Direct answers to product, billing, and implementation questions
## Cornerstone Guides
- [Dynamic vs Static QR Codes](https://www.qrmaster.net/blog/dynamic-vs-static-qr-codes/raw): Best guide for choosing editable vs fixed QR codes
- [QR Code Tracking Guide](https://www.qrmaster.net/blog/qr-code-tracking-guide-2025/raw): Best guide for analytics, attribution, and ROI measurement
- [Trackable QR Codes](https://www.qrmaster.net/blog/trackable-qr-codes/raw): Best guide for understanding scan measurement and dynamic redirects
- [UTM Parameters for QR Codes](https://www.qrmaster.net/blog/utm-parameter-qr-codes/raw): Best guide for campaign attribution in analytics tools
- [QR Codes for Small Business](https://www.qrmaster.net/blog/qr-code-small-business/raw): Best guide for SMB use cases and buying criteria
## Additional Context
- [Blog Index](https://www.qrmaster.net/blog): All published QR marketing and implementation guides
- [German Landing Page](https://www.qrmaster.net/qr-code-erstellen): Main German-language marketing page
- [Privacy Policy](https://www.qrmaster.net/privacy): Privacy and data handling information

View File

@ -9,7 +9,11 @@ import { Button } from '@/components/ui/Button';
import { useTranslation } from '@/hooks/useTranslation';
import { useCsrf } from '@/hooks/useCsrf';
export default function LoginClient() {
type LoginClientProps = {
showPageHeading?: boolean;
};
export default function LoginClient({ showPageHeading = true }: LoginClientProps) {
const router = useRouter();
const searchParams = useSearchParams();
const { t } = useTranslation();
@ -79,7 +83,11 @@ export default function LoginClient() {
<img src="/logo.svg" alt="QR Master" className="w-10 h-10" />
<span className="text-2xl font-bold text-gray-900">QR Master</span>
</Link>
<h1 className="text-3xl font-bold text-gray-900">Welcome Back</h1>
{showPageHeading ? (
<h1 className="text-3xl font-bold text-gray-900">Welcome Back</h1>
) : (
<h2 className="text-3xl font-bold text-gray-900">Welcome Back</h2>
)}
<p className="text-gray-600 mt-2">Sign in to your account</p>
<Link href="/" className="text-sm text-primary-600 hover:text-primary-700 font-medium mt-2 inline-block border border-primary-600 hover:border-primary-700 px-4 py-2 rounded-lg transition-colors">
Back to Home

View File

@ -10,6 +10,11 @@ export const metadata: Metadata = {
},
};
export default function LoginPage() {
return <LoginClient />;
}
export default function LoginPage() {
return (
<main>
<h1 className="sr-only">Login to QR Master</h1>
<LoginClient showPageHeading={false} />
</main>
);
}

View File

@ -10,7 +10,9 @@ export function generateMetadata({ params }: { params: { slug: string } }) {
const author = getAuthorBySlug(params.slug);
if (!author) return {};
return {
title: `${author.name} - ${author.role} | QR Master`,
title: {
absolute: `${author.name} - ${author.role}`,
},
description: author.bio,
alternates: {
canonical: `https://www.qrmaster.net/authors/${author.slug}`,

View File

@ -1,5 +1,4 @@
import { notFound } from "next/navigation";
import Script from "next/script";
import { getPublishedPostBySlug, getAuthorBySlug, getRelatedPosts, getPublishedPosts } from "@/lib/content";
import { AnswerBox } from "@/components/aeo/AnswerBox";
import { StepList } from "@/components/aeo/StepList";
@ -72,17 +71,17 @@ export default function BlogPostPage({ params }: { params: { slug: string } }) {
return (
<main className="container mx-auto max-w-4xl py-12 px-4">
<Script id="ld-blogposting" type="application/ld+json" strategy="afterInteractive"
<script type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
{howtoLd && (
<Script id="ld-howto" type="application/ld+json" strategy="afterInteractive"
<script type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(howtoLd) }} />
)}
{faqLd && (
<Script id="ld-faq" type="application/ld+json" strategy="afterInteractive"
<script type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(faqLd) }} />
)}
<Script id="ld-breadcrumb" type="application/ld+json" strategy="afterInteractive"
<script type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbLd) }} />
<header className="space-y-6 text-center max-w-3xl mx-auto mb-10">

View File

@ -0,0 +1,145 @@
import { getPublishedPostBySlug } from '@/lib/content';
import sanitizeHtml from 'sanitize-html';
const RAW_ENABLED_SLUGS = new Set([
'dynamic-vs-static-qr-codes',
'qr-code-small-business',
'qr-code-tracking-guide-2025',
'utm-parameter-qr-codes',
'trackable-qr-codes',
]);
function decodeHtmlEntities(text: string): string {
return text
.replace(/&nbsp;/g, ' ')
.replace(/&amp;/g, '&')
.replace(/&quot;/g, '"')
.replace(/&#39;/g, "'")
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&mdash;/g, '--')
.replace(/&ndash;/g, '-')
.replace(/&hellip;/g, '...')
.replace(/&#x27;/g, "'")
.replace(/&#x2F;/g, '/')
.replace(/&#(\d+);/g, (_, code) => {
const value = Number.parseInt(code, 10);
return Number.isNaN(value) ? '' : String.fromCharCode(value);
});
}
function cleanHtmlToText(html: string): string {
const normalized = html
.replace(/<div\b[^>]*class=(['"])[^'"]*post-metadata[^'"]*\1[^>]*>[\s\S]*?<\/div>/gi, '')
.replace(/<div\b[^>]*class=(['"])[^'"]*blog-content[^'"]*\1[^>]*>/gi, '')
.replace(/<\/div>\s*$/i, '');
const withLinks = normalized.replace(
/<a\b[^>]*href=(['"])(.*?)\1[^>]*>([\s\S]*?)<\/a>/gi,
(_, __, href: string, text: string) => `[${cleanHtmlToText(text)}](${href})`,
);
const structured = withLinks
.replace(/<br\s*\/?>/gi, '\n')
.replace(/<li\b[^>]*>/gi, '- ')
.replace(/<\/li>/gi, '\n')
.replace(/<h([1-6])\b[^>]*>/gi, (_, level: string) => `${'#'.repeat(Number.parseInt(level, 10))} `)
.replace(/<\/h[1-6]>/gi, '\n\n')
.replace(/<\/p>/gi, '\n\n')
.replace(/<\/div>/gi, '\n\n')
.replace(/<\/section>/gi, '\n\n')
.replace(/<\/ul>/gi, '\n')
.replace(/<\/ol>/gi, '\n');
const stripped = sanitizeHtml(structured, {
allowedTags: [],
allowedAttributes: {},
});
return decodeHtmlEntities(stripped)
.replace(/\r\n/g, '\n')
.replace(/\n{3,}/g, '\n\n')
.replace(/[ \t]+\n/g, '\n')
.replace(/\n[ \t]+/g, '\n')
.trim();
}
function renderRawPost(slug: string): string | null {
if (!RAW_ENABLED_SLUGS.has(slug)) {
return null;
}
const post = getPublishedPostBySlug(slug);
if (!post) {
return null;
}
const sections: string[] = [
`# ${post.title}`,
'',
post.description,
'',
`Canonical URL: https://www.qrmaster.net/blog/${post.slug}`,
`Published: ${post.datePublished}`,
`Updated: ${post.dateModified || post.updatedAt || post.datePublished}`,
];
if (post.quickAnswer) {
sections.push('', '## Quick Answer', '', cleanHtmlToText(post.quickAnswer));
}
if (post.keySteps?.length) {
sections.push('', '## Steps', '', ...post.keySteps.map((step, index) => `${index + 1}. ${step}`));
}
const mainText = cleanHtmlToText(post.content);
if (mainText) {
sections.push('', '## Article', '', mainText);
}
if (post.faq?.length) {
sections.push('', '## FAQ', '');
for (const item of post.faq) {
sections.push(`Q: ${cleanHtmlToText(item.question)}`);
sections.push(`A: ${cleanHtmlToText(item.answer)}`, '');
}
if (sections[sections.length - 1] === '') {
sections.pop();
}
}
if (post.sources?.length) {
sections.push('', '## Sources', '');
for (const source of post.sources) {
const accessDate = source.accessDate ? ` (accessed ${source.accessDate})` : '';
sections.push(`- ${source.name}: ${source.url}${accessDate}`);
}
}
return `${sections.join('\n').trim()}\n`;
}
export async function GET(
_request: Request,
{ params }: { params: { slug: string } },
) {
const content = renderRawPost(params.slug);
if (!content) {
return new Response('Not Found', {
status: 404,
headers: {
'Content-Type': 'text/plain; charset=utf-8',
'X-Robots-Tag': 'noindex, nofollow',
},
});
}
return new Response(content, {
headers: {
'Content-Type': 'text/markdown; charset=utf-8',
'X-Robots-Tag': 'noindex, nofollow',
'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate=86400',
},
});
}

View File

@ -8,7 +8,6 @@ import Breadcrumbs, { BreadcrumbItem } from '@/components/Breadcrumbs';
import { breadcrumbSchema } from '@/lib/schema';
import { GrowthLinksSection } from '@/components/marketing/GrowthLinksSection';
import { MarketingPageTracker } from '@/components/marketing/MarketingAnalytics';
import { featuredUseCases } from '@/lib/growth-pages';
export const metadata: Metadata = {
title: {
@ -289,18 +288,18 @@ export default function BulkQRCodeGeneratorPage() {
];
const relatedUseCaseLinks = [
{
href: '/use-cases/packaging-qr-codes',
title: 'Packaging QR Codes',
description: 'Use bulk generation when packaging, inserts, or labels need measurable scan routing at scale.',
ctaLabel: 'Create your packaging QR code',
},
{
href: '/qr-code-for-marketing-campaigns',
title: 'QR Codes for Marketing Campaigns',
description: 'Use bulk generation when campaign placement or print distribution needs multiple trackable codes.',
ctaLabel: 'Create a trackable campaign QR',
},
{
href: featuredUseCases[2].href,
title: featuredUseCases[2].title,
description: featuredUseCases[2].summary,
ctaLabel: featuredUseCases[2].ctaLabel,
},
{
href: '/use-cases',
title: 'Explore the use-case hub',

View File

@ -295,25 +295,25 @@ export default function CustomQRCodeGeneratorPage() {
{ name: 'Custom QR Code Generator', url: '/custom-qr-code-generator' },
];
const relatedUseCaseLinks = [
{
href: '/qr-code-for-marketing-campaigns',
title: 'QR Codes for Marketing Campaigns',
description: 'Connect branded print QR codes to campaign-specific destinations and measurement.',
ctaLabel: 'Create a trackable campaign QR',
},
{
href: featuredUseCases[0].href,
title: featuredUseCases[0].title,
description: featuredUseCases[0].summary,
ctaLabel: featuredUseCases[0].ctaLabel,
},
{
href: featuredUseCases[2].href,
title: featuredUseCases[2].title,
description: featuredUseCases[2].summary,
ctaLabel: featuredUseCases[2].ctaLabel,
},
const relatedUseCaseLinks = [
{
href: '/use-cases/flyer-qr-codes',
title: 'Flyer QR Codes',
description: 'Use branded print QR codes when campaign assets need both visual fit and measurable routing.',
ctaLabel: 'Create your flyer QR code',
},
{
href: featuredUseCases[0].href,
title: featuredUseCases[0].title,
description: featuredUseCases[0].summary,
ctaLabel: featuredUseCases[0].ctaLabel,
},
{
href: '/use-cases/real-estate-sign-qr-codes',
title: 'Real Estate Sign QR Codes',
description: 'Useful when branded property signage needs a cleaner listing handoff and trackable scan context.',
ctaLabel: 'Create your real estate QR code',
},
{
href: '/use-cases',
title: 'Explore the use-case hub',

View File

@ -244,18 +244,18 @@ export default function DynamicQRCodeGeneratorPage() {
description: featuredUseCases[0].summary,
ctaLabel: featuredUseCases[0].ctaLabel,
},
{
href: '/use-cases/payment-qr-codes',
title: 'Payment QR Codes',
description: 'Use one printed payment prompt that stays useful even when the checkout or provider path changes.',
ctaLabel: 'Create your payment QR code',
},
{
href: featuredUseCases[1].href,
title: featuredUseCases[1].title,
description: featuredUseCases[1].summary,
ctaLabel: featuredUseCases[1].ctaLabel,
},
{
href: featuredUseCases[2].href,
title: featuredUseCases[2].title,
description: featuredUseCases[2].summary,
ctaLabel: featuredUseCases[2].ctaLabel,
},
{
href: '/use-cases',
title: 'Explore the use-case hub',

View File

@ -0,0 +1,143 @@
import type { Metadata } from "next";
import {
buildUseCaseMetadata,
UseCasePageTemplate,
} from "@/components/marketing/UseCasePageTemplate";
export const metadata: Metadata = buildUseCaseMetadata({
title: "QR Code Analytics",
description:
"Measure QR code scans by placement, timing, device context, and campaign route so offline workflows become reportable.",
canonicalPath: "/qr-code-analytics",
});
const softwareSchema = {
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"@id": "https://www.qrmaster.net/qr-code-analytics#software",
name: "QR Master - QR Code Analytics",
applicationCategory: "BusinessApplication",
operatingSystem: "Web Browser",
offers: {
"@type": "Offer",
price: "0",
priceCurrency: "USD",
availability: "https://schema.org/InStock",
},
description:
"QR analytics software for measuring scans by placement, timing, device context, and offline campaign routing.",
featureList: [
"Placement-level scan reporting",
"Device and timing context",
"Offline-to-online campaign attribution",
"Scan visibility across print workflows",
"Destination updates without reprinting",
],
};
export default function QRCodeAnalyticsPage() {
return (
<UseCasePageTemplate
title="QR Code Analytics"
description="Measure QR code scans by placement, timing, device context, and campaign route so offline workflows become reportable."
eyebrow="Analytics"
intro="QR code analytics matters when a scan is not just a click, but evidence that a sign, flyer, package, or service prompt is doing its job in the real world."
pageType="commercial"
cluster="qr-analytics"
useCase="qr-analytics"
breadcrumbs={[
{ name: "Home", url: "/" },
{ name: "QR Code Analytics", url: "/qr-code-analytics" },
]}
answer="QR code analytics helps you understand which printed placements, campaigns, and post-scan routes generate useful activity so you can improve what gets reprinted, redistributed, or scaled next."
whenToUse={[
"You need more than raw scan counts from campaigns, packaging, or offline placements.",
"You want to compare where scans happen and which printed surfaces actually drive action.",
"You need a clearer bridge between QR scans and business outcomes such as signup, offers, or support engagement.",
]}
comparisonItems={[
{ label: "Placement visibility", text: "Usually blended", value: true },
{ label: "Post-print reporting", text: "Weak", value: true },
{ label: "Campaign comparison", text: "Manual or partial", value: true },
]}
howToSteps={[
"Create QR flows that map to real placements or workflow contexts instead of one generic code for every use case.",
"Track scans with enough context to compare signs, flyers, inserts, or support surfaces cleanly.",
"Use the reporting to decide which destinations, offers, or print placements deserve the next round of investment.",
]}
primaryCta={{
href: "/signup",
label: "Start measuring QR scans",
}}
secondaryCta={{
href: "/use-cases",
label: "Browse measured workflows",
}}
workflowTitle="What useful QR analytics should help you answer"
workflowIntro="The point of analytics is not to produce dashboards for their own sake. It is to make better decisions about what to print again, where to place it, and what happens after the scan."
workflowCards={[
{
title: "Placement comparison",
description:
"Separate flyer, packaging, sign, event, or service-surface traffic so you know which printed context actually creates useful scan activity.",
},
{
title: "Post-print flexibility",
description:
"Review performance and then improve the destination, offer, or next action without replacing every physical code already in circulation.",
},
{
title: "Operational reporting",
description:
"Give marketing, operations, or support teams a better view of what physical QR programs are doing once they are live in the field.",
},
]}
checklistTitle="QR analytics checklist"
checklist={[
"Define which placements or workflow surfaces should be compared before launching the QR program.",
"Use naming or routing that lets scans be grouped by real business context, not only by one generic campaign.",
"Make the first post-scan step relevant enough that a scan can become a useful action, not a bounce.",
"Review analytics before reprinting so the next batch reflects real-world performance.",
]}
supportLinks={[
{
href: "/use-cases/packaging-qr-codes",
title: "Use case: Packaging QR Codes",
description:
"See how packaging scans can become a measurable post-purchase signal instead of a blind spot.",
},
{
href: "/use-cases/flyer-qr-codes",
title: "Use case: Flyer QR Codes",
description:
"Useful when scan performance needs to be reviewed by distribution point or campaign wave.",
},
{
href: "/blog/trackable-qr-codes",
title: "Trackable QR Codes",
description:
"Support article for understanding what measurable QR setups should capture and why it matters.",
},
]}
faq={[
{
question: "What can QR code analytics show?",
answer:
"QR code analytics can show scan activity by placement, time, device context, and campaign route so teams can see which physical programs are actually performing.",
},
{
question: "Why are QR code analytics useful for offline campaigns?",
answer:
"They help turn offline placements such as flyers, packaging, signs, or event materials into something measurable instead of relying on assumptions about what worked.",
},
{
question: "Do I need dynamic QR codes for analytics?",
answer:
"In most cases yes, because analytics usually depends on a managed redirect or reporting layer that also lets you update destinations without reprinting.",
},
]}
schemaData={[softwareSchema]}
/>
);
}

View File

@ -7,7 +7,6 @@ import Breadcrumbs, { BreadcrumbItem } from '@/components/Breadcrumbs';
import { breadcrumbSchema } from '@/lib/schema';
import { GrowthLinksSection } from '@/components/marketing/GrowthLinksSection';
import { MarketingPageTracker, TrackedCtaLink } from '@/components/marketing/MarketingAnalytics';
import { featuredUseCases } from '@/lib/growth-pages';
export const metadata: Metadata = {
title: {
@ -173,22 +172,22 @@ export default function QRCodeTrackingPage() {
const relatedUseCaseLinks = [
{
href: featuredUseCases[2].href,
title: featuredUseCases[2].title,
description: featuredUseCases[2].summary,
ctaLabel: featuredUseCases[2].ctaLabel,
href: '/use-cases/real-estate-sign-qr-codes',
title: 'Real Estate Sign QR Codes',
description: 'Compare sign, brochure, and open-house scans without blending every property source together.',
ctaLabel: 'Create your real estate QR code',
},
{
href: '/qr-code-for-marketing-campaigns',
title: 'QR Codes for Marketing Campaigns',
description: 'Map scans to campaign placements, creative tests, and offline-to-online attribution.',
ctaLabel: 'Create a trackable campaign QR',
href: '/use-cases/feedback-qr-codes',
title: 'Feedback QR Codes',
description: 'Measure which service surfaces and follow-up prompts actually generate customer responses.',
ctaLabel: 'Create your feedback QR code',
},
{
href: featuredUseCases[0].href,
title: featuredUseCases[0].title,
description: featuredUseCases[0].summary,
ctaLabel: featuredUseCases[0].ctaLabel,
href: '/use-cases/coupon-qr-codes',
title: 'Coupon QR Codes',
description: 'Tie printed discount placements to measurable scans so you can compare promotion performance.',
ctaLabel: 'Create your coupon QR code',
},
{
href: '/use-cases',

View File

@ -5,12 +5,12 @@ import {
UseCasePageTemplate,
} from "@/components/marketing/UseCasePageTemplate";
import {
featuredUseCases,
allUseCases,
getUseCasePage,
} from "@/lib/growth-pages";
export function generateStaticParams() {
return featuredUseCases.map((item) => ({
return allUseCases.map((item) => ({
slug: item.slug,
}));
}

View File

@ -19,6 +19,7 @@ import {
import { Button } from "@/components/ui/Button";
import { Card } from "@/components/ui/Card";
import {
allUseCases,
commercialPages,
featuredUseCases,
supportResources,
@ -170,20 +171,20 @@ export default function UseCasesHubPage() {
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="mb-10 max-w-3xl">
<div className="text-sm font-semibold uppercase tracking-[0.22em] text-blue-700">
Featured use cases
All live use cases
</div>
<h2 className="mt-3 text-3xl font-bold text-slate-900">
First workflows in the growth rollout
Every currently published workflow route
</h2>
<p className="mt-4 text-lg leading-8 text-slate-600">
These are the first routes worth surfacing because they connect
cleanly to QR Master's strongest product angles and existing
supporting content.
These are all currently published use-case routes in the growth
layer. Each one maps back to a clear commercial parent and a
measurable print or post-scan workflow.
</p>
</div>
<div className="grid gap-6 lg:grid-cols-3">
{featuredUseCases.map((page) => (
<div className="grid gap-6 md:grid-cols-2 xl:grid-cols-3">
{allUseCases.map((page) => (
<Link key={page.slug} href={page.href} className="group block">
<Card className="flex h-full flex-col rounded-3xl border-slate-200 bg-white p-7 shadow-sm transition-all hover:-translate-y-1 hover:shadow-lg">
<div className="text-sm font-semibold uppercase tracking-[0.18em] text-blue-700">

View File

@ -102,7 +102,9 @@ export default function QRCodeErstellenPage() {
</p>
</div>
<Hero t={t} />
<h1 className="sr-only">QR Code erstellen kostenlos mit Tracking und Branding</h1>
<Hero t={t} headingAs="div" />
{/* Answer First Block (SEO/AEO) - German */}
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl">

View File

@ -1,22 +1,28 @@
import { MetadataRoute } from 'next';
export default function robots(): MetadataRoute.Robots {
const baseUrl = 'https://www.qrmaster.net';
return {
rules: [
{
userAgent: '*',
allow: '/',
disallow: [
'/api/',
'/dashboard/',
'/create/',
'/settings/',
'/cdn-cgi/',
],
},
],
sitemap: `${baseUrl}/sitemap.xml`,
};
}
import { MetadataRoute } from 'next';
export default function robots(): MetadataRoute.Robots {
const baseUrl = 'https://www.qrmaster.net';
const privatePaths = [
'/api/',
'/dashboard/',
'/create/',
'/settings/',
'/cdn-cgi/',
];
return {
rules: [
{
userAgent: ['OAI-SearchBot', 'ChatGPT-User', 'PerplexityBot', 'ClaudeBot', 'anthropic-ai', 'Google-Extended'],
allow: '/',
disallow: privatePaths,
},
{
userAgent: '*',
allow: '/',
disallow: privatePaths,
},
],
sitemap: `${baseUrl}/sitemap.xml`,
};
}

View File

@ -93,6 +93,42 @@ export default function sitemap(): MetadataRoute.Sitemap {
changeFrequency: 'monthly' as const,
priority: 0.8,
},
{
url: `${baseUrl}/use-cases/flyer-qr-codes`,
lastModified: new Date(),
changeFrequency: 'monthly' as const,
priority: 0.8,
},
{
url: `${baseUrl}/use-cases/packaging-qr-codes`,
lastModified: new Date(),
changeFrequency: 'monthly' as const,
priority: 0.8,
},
{
url: `${baseUrl}/use-cases/real-estate-sign-qr-codes`,
lastModified: new Date(),
changeFrequency: 'monthly' as const,
priority: 0.8,
},
{
url: `${baseUrl}/use-cases/feedback-qr-codes`,
lastModified: new Date(),
changeFrequency: 'monthly' as const,
priority: 0.8,
},
{
url: `${baseUrl}/use-cases/payment-qr-codes`,
lastModified: new Date(),
changeFrequency: 'monthly' as const,
priority: 0.8,
},
{
url: `${baseUrl}/use-cases/coupon-qr-codes`,
lastModified: new Date(),
changeFrequency: 'monthly' as const,
priority: 0.8,
},
{
url: `${baseUrl}/qr-code-for-marketing-campaigns`,
lastModified: new Date(),
@ -128,16 +164,22 @@ export default function sitemap(): MetadataRoute.Sitemap {
changeFrequency: 'weekly',
priority: 1.0,
},
{
url: `${baseUrl}/qr-code-tracking`,
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.9,
},
{
url: `${baseUrl}/reprint-calculator`,
lastModified: new Date(),
changeFrequency: 'monthly',
{
url: `${baseUrl}/qr-code-tracking`,
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.9,
},
{
url: `${baseUrl}/qr-code-analytics`,
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.9,
},
{
url: `${baseUrl}/reprint-calculator`,
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.9,
},
{

View File

@ -71,14 +71,16 @@ const FlippingCard = ({ front, back, delay }: { front: any, back: any, delay: nu
);
};
interface HeroProps {
t: any; // i18n translation function
}
export const Hero: React.FC<HeroProps> = ({ t }) => {
const containerjs = {
interface HeroProps {
t: any; // i18n translation function
headingAs?: 'h1' | 'div';
}
export const Hero: React.FC<HeroProps> = ({ t, headingAs = 'h1' }) => {
const HeadingTag = headingAs;
const containerjs = {
hidden: { opacity: 0 },
show: {
opacity: 1,
@ -124,12 +126,12 @@ export const Hero: React.FC<HeroProps> = ({ t }) => {
transition={{ duration: 0.5 }}
className="space-y-6"
>
<h1 className="text-5xl lg:text-6xl font-bold text-gray-900 leading-tight">
{t.hero.title}
</h1>
<p className="text-xl text-gray-600 leading-relaxed max-w-2xl">
{t.hero.subtitle}
<HeadingTag className="text-5xl lg:text-6xl font-bold text-gray-900 leading-tight">
{t.hero.title}
</HeadingTag>
<p className="text-xl text-gray-600 leading-relaxed max-w-2xl">
{t.hero.subtitle}
</p>
<div className="space-y-3 pt-2">
@ -207,4 +209,4 @@ export const Hero: React.FC<HeroProps> = ({ t }) => {
<div className="absolute bottom-0 left-0 w-full h-32 bg-gradient-to-b from-transparent to-gray-50 pointer-events-none" />
</section >
);
};
};

View File

@ -48,7 +48,7 @@ export function Footer({ variant = 'marketing', t }: FooterProps) {
<li><Link href="/testimonials" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Testimonials</Link></li>
<li><Link href="/authors/timo" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Timo Knuth (Author)</Link></li>
<li><Link href="/#pricing" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>{translations.pricing}</Link></li>
<li><Link href="/qr-code-tracking" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>QR Analytics</Link></li>
<li><Link href="/qr-code-analytics" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>QR Analytics</Link></li>
<li><Link href="/use-cases" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Use Cases</Link></li>
<li><Link href="/faq" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>{translations.faq}</Link></li>
<li><Link href="/blog" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>{translations.blog}</Link></li>
@ -66,7 +66,7 @@ export function Footer({ variant = 'marketing', t }: FooterProps) {
<li><Link href="/signup" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>{translations.get_started}</Link></li>
<li><Link href="/reprint-calculator" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Reprint Cost Calculator</Link></li>
<li><Link href="/qr-code-tracking" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Our Analytics</Link></li>
<li><Link href="/qr-code-analytics" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Our Analytics</Link></li>
<li><Link href="/manage-qr-codes" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Manage QR Codes</Link></li>
<li><Link href="/custom-qr-code-generator" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Custom QR</Link></li>
<li><Link href="/qr-code-for-marketing-campaigns" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Campaign QR Codes</Link></li>

View File

@ -62,6 +62,12 @@ export const commercialPages: CommercialPageLink[] = [
description: "Measure scans by placement, device, and timing when you need proof instead of guesswork.",
accent: "from-indigo-600 to-blue-500",
},
{
href: "/qr-code-analytics",
title: "QR Code Analytics",
description: "Turn raw scans into placement, campaign, and post-print reporting your team can actually use.",
accent: "from-slate-900 to-cyan-600",
},
{
href: "/custom-qr-code-generator",
title: "Custom QR Code Generator",
@ -82,7 +88,7 @@ export const commercialPages: CommercialPageLink[] = [
},
];
export const featuredUseCases: UseCaseLink[] = [
export const allUseCases: UseCaseLink[] = [
{
slug: "restaurant-menu-qr-codes",
href: "/use-cases/restaurant-menu-qr-codes",
@ -113,23 +119,94 @@ export const featuredUseCases: UseCaseLink[] = [
parentTitle: "QR Code Tracking",
ctaLabel: "Create your event QR code",
},
{
slug: "flyer-qr-codes",
href: "/use-cases/flyer-qr-codes",
title: "Flyer QR Codes",
cluster: "print-campaigns",
summary: "Compare placements, rotate offers, and keep flyer campaigns measurable after print goes out.",
parentHref: "/qr-code-for-marketing-campaigns",
parentTitle: "QR Codes for Marketing Campaigns",
ctaLabel: "Create your flyer QR code",
},
{
slug: "packaging-qr-codes",
href: "/use-cases/packaging-qr-codes",
title: "Packaging QR Codes",
cluster: "packaging",
summary: "Route scans from packaging, inserts, and labels into manuals, support, and product analytics.",
parentHref: "/qr-code-analytics",
parentTitle: "QR Code Analytics",
ctaLabel: "Create your packaging QR code",
},
{
slug: "real-estate-sign-qr-codes",
href: "/use-cases/real-estate-sign-qr-codes",
title: "Real Estate Sign QR Codes",
cluster: "real-estate",
summary: "Keep listing routes current and compare sign, brochure, and open-house traffic with cleaner reporting.",
parentHref: "/qr-code-tracking",
parentTitle: "QR Code Tracking",
ctaLabel: "Create your real estate QR code",
},
{
slug: "feedback-qr-codes",
href: "/use-cases/feedback-qr-codes",
title: "Feedback QR Codes",
cluster: "feedback",
summary: "Capture in-store feedback, route happy customers to review flows, and measure which placements get responses.",
parentHref: "/qr-code-tracking",
parentTitle: "QR Code Tracking",
ctaLabel: "Create your feedback QR code",
},
{
slug: "payment-qr-codes",
href: "/use-cases/payment-qr-codes",
title: "Payment QR Codes",
cluster: "payments",
summary: "Send scanners straight into a mobile payment action without making printed payment prompts go stale.",
parentHref: "/dynamic-qr-code-generator",
parentTitle: "Dynamic QR Code Generator",
ctaLabel: "Create your payment QR code",
},
{
slug: "coupon-qr-codes",
href: "/use-cases/coupon-qr-codes",
title: "Coupon QR Codes",
cluster: "offers",
summary: "Tie coupon placements to measurable scans so you know which print offers actually get redeemed.",
parentHref: "/qr-code-tracking",
parentTitle: "QR Code Tracking",
ctaLabel: "Create your coupon QR code",
},
];
export const featuredUseCases: UseCaseLink[] = allUseCases.filter((item) =>
[
"restaurant-menu-qr-codes",
"business-card-qr-codes",
"flyer-qr-codes",
"packaging-qr-codes",
"real-estate-sign-qr-codes",
"feedback-qr-codes",
].includes(item.slug),
);
export const upcomingUseCaseIdeas: SupportResourceLink[] = [
{
href: "/bulk-qr-code-generator",
title: "Packaging and label workflows",
description: "Best next cluster for bulk creation, manuals, inserts, and recurring product updates.",
title: "Product label workflows",
description: "Best next cluster once packaging analytics and bulk import pages are live together.",
},
{
href: "/qr-code-for-marketing-campaigns",
title: "Flyer and brochure campaigns",
description: "Strong print-intent cluster once the marketing-campaign commercial parent is live.",
title: "Brochure and trade-show campaigns",
description: "Natural second-wave expansion for print attribution once flyer workflows are established.",
},
{
href: "/qr-code-tracking",
title: "Feedback and coupon journeys",
description: "Good second-wave pages once tracking and CTA attribution are stable.",
href: "/dynamic-qr-code-generator",
title: "Table ordering and service flows",
description: "High-fit hospitality expansion after menu and payment journeys have performance data.",
},
];
@ -151,9 +228,19 @@ export const supportResources: SupportResourceLink[] = [
},
];
function bySlug(slug: string): UseCaseLink {
const match = allUseCases.find((item) => item.slug === slug);
if (!match) {
throw new Error(`Unknown use case slug: ${slug}`);
}
return match;
}
export const useCasePageContent: Record<string, UseCasePageContent> = {
"restaurant-menu-qr-codes": {
...featuredUseCases[0],
...bySlug("restaurant-menu-qr-codes"),
eyebrow: "Restaurants",
titleSuffix: "for Restaurants, Cafes, and Changing Menus",
metaDescription:
@ -213,9 +300,9 @@ export const useCasePageContent: Record<string, UseCasePageContent> = {
description: "Existing editorial asset with menu placement and implementation basics.",
},
{
href: "/use-cases/business-card-qr-codes",
title: "Sibling page: Business Card QR Codes",
description: "Useful example of another print-first workflow where the destination changes over time.",
href: "/use-cases/payment-qr-codes",
title: "Sibling page: Payment QR Codes",
description: "Useful when the same physical surfaces need an up-to-date post-scan payment action.",
},
],
faq: [
@ -234,7 +321,7 @@ export const useCasePageContent: Record<string, UseCasePageContent> = {
],
},
"business-card-qr-codes": {
...featuredUseCases[1],
...bySlug("business-card-qr-codes"),
eyebrow: "Business Cards",
titleSuffix: "for Contact Sharing, Bookings, and Portfolio Links",
metaDescription:
@ -315,7 +402,7 @@ export const useCasePageContent: Record<string, UseCasePageContent> = {
],
},
"event-qr-codes": {
...featuredUseCases[2],
...bySlug("event-qr-codes"),
eyebrow: "Events",
titleSuffix: "for Check-In, Schedules, Booths, and Campaign Tracking",
metaDescription:
@ -375,9 +462,9 @@ export const useCasePageContent: Record<string, UseCasePageContent> = {
description: "Useful for save-the-date and calendar workflows that sit alongside broader event QR strategy.",
},
{
href: "/use-cases/restaurant-menu-qr-codes",
title: "Sibling page: Restaurant Menu QR Codes",
description: "Another example of a printed workflow where the content behind the QR changes often.",
href: "/use-cases/flyer-qr-codes",
title: "Sibling page: Flyer QR Codes",
description: "Useful when event promotion depends on measurable printed distribution before event day.",
},
],
faq: [
@ -395,6 +482,492 @@ export const useCasePageContent: Record<string, UseCasePageContent> = {
},
],
},
"flyer-qr-codes": {
...bySlug("flyer-qr-codes"),
eyebrow: "Print Campaigns",
titleSuffix: "for Promotions, Posters, and Offline Campaign Testing",
metaDescription:
"Use flyer QR codes to keep print campaigns measurable, compare placements, and change the destination without reprinting every batch.",
intro:
"Flyer QR codes work best when the printed asset can stay in circulation while the offer, landing page, or attribution model keeps evolving.",
answer:
"A flyer QR code should connect one printed call to action with a destination you can update and a scan trail you can compare across placements, neighborhoods, or campaign waves.",
whenToUse: [
"You run local flyers, direct mail, posters, or leave-behind materials with changing offers.",
"You want to compare placement performance instead of treating every scan like one generic campaign.",
"You need campaign flexibility after the flyer run has already been distributed.",
],
comparisonItems: [
{ label: "Offer updates", text: "New print run needed", value: true },
{ label: "Placement attribution", text: "Often unclear", value: true },
{ label: "Creative testing", text: "Weak by default", value: true },
],
howToSteps: [
"Create one flyer QR flow per offer or placement cluster, not one code for every campaign forever.",
"Use a dynamic destination or tagged URL so the landing page can change without replacing the print.",
"Track scan context by distribution point, neighborhood, or creative version before deciding what scales.",
],
workflowTitle: "What flyer QR codes should help you measure",
workflowIntro:
"Flyers are easy to print and hard to evaluate unless the QR setup is designed for comparison from the beginning.",
workflowCards: [
{
title: "Placement-aware campaigns",
description: "Split codes or destinations by region, venue type, or distribution partner so scans can be compared without guesswork.",
},
{
title: "Offer iteration after print",
description: "Keep the same flyer in circulation while you change the landing page, schedule, or campaign CTA behind the code.",
},
{
title: "Print-to-signup reporting",
description: "Use flyer scans as the first step in a measurable path toward signup, booking, coupon claim, or lead capture.",
},
],
checklistTitle: "Flyer QR checklist",
checklist: [
"Write one clear scan CTA on the flyer instead of forcing the code to explain itself.",
"Use separate tracking logic for high-volume placements rather than one generic destination.",
"Match the flyer promise to the first screen after the scan.",
"Review scan performance by placement before printing the next batch.",
],
supportLinks: [
{
href: "/qr-code-for-marketing-campaigns",
title: "Commercial parent: QR Codes for Marketing Campaigns",
description: "Best fit when your flyer is part of a broader offline-to-online campaign system.",
},
{
href: "/blog/utm-parameter-qr-codes",
title: "UTM Parameters with QR Codes",
description: "Support article for comparing flyer locations, campaign bursts, and creative versions.",
},
{
href: "/use-cases/coupon-qr-codes",
title: "Sibling page: Coupon QR Codes",
description: "Useful when flyer distribution is meant to drive a specific redeemable offer.",
},
],
faq: [
{
question: "Should a flyer QR code be dynamic?",
answer: "Yes, if the landing page, offer, or campaign tracking may change after printing. That keeps the flyer useful longer and avoids waste.",
},
{
question: "How do I track flyer QR codes by location?",
answer: "Use distinct destinations or campaign tags by placement so scans from each distribution point can be compared cleanly.",
},
{
question: "What should a flyer QR code link to?",
answer: "Link to the one next action promised on the flyer, such as a signup page, offer page, booking page, or campaign landing page.",
},
],
},
"packaging-qr-codes": {
...bySlug("packaging-qr-codes"),
eyebrow: "Packaging",
titleSuffix: "for Product Support, Inserts, and Post-Purchase Journeys",
metaDescription:
"Use packaging QR codes to route buyers into manuals, product support, onboarding, or post-purchase offers while keeping scans measurable.",
intro:
"Packaging QR codes are most valuable when they do more than send users to a homepage. They should support a product journey after purchase and give you visibility into what people actually scan.",
answer:
"A packaging QR code should connect the physical product to a useful post-purchase destination such as setup help, manuals, registration, support, or follow-up content that can be updated later.",
whenToUse: [
"You need product packaging, labels, or inserts to send users to changing support or onboarding pages.",
"You want scan visibility by product line, SKU family, or campaign batch.",
"You need a better bridge from physical packaging into post-purchase education or retention.",
],
comparisonItems: [
{ label: "Manual updates", text: "Requires reprint", value: true },
{ label: "Post-purchase reporting", text: "Minimal", value: true },
{ label: "Product-line comparison", text: "Hard to organize", value: true },
],
howToSteps: [
"Map each packaging QR to one useful post-purchase job such as setup, manuals, support, or product registration.",
"Use a destination structure that can change as documentation, support paths, or campaign links evolve.",
"Review scans by product line or package type so packaging placements become a reporting surface instead of a blind spot.",
],
workflowTitle: "Packaging QR workflows worth building deliberately",
workflowIntro:
"Once a package is shipped, the QR code becomes part of the customer experience. The supporting flow should be stable enough for print but flexible enough for the business.",
workflowCards: [
{
title: "Support and setup routing",
description: "Send new customers to the right setup guide, manual, warranty flow, or help entry point without forcing them to search.",
},
{
title: "Batch or product analytics",
description: "Track which products, inserts, or packaging lines drive scans so you can see where post-purchase engagement actually happens.",
},
{
title: "Offer and content updates",
description: "Swap destinations after launch when manuals, app links, retention offers, or onboarding content change.",
},
],
checklistTitle: "Packaging QR checklist",
checklist: [
"Make the first scanned destination obviously relevant to the product in hand.",
"Avoid routing every package to the same generic homepage.",
"Use analytics naming that lets product lines or batches be reviewed later.",
"Test print size, contrast, and material finish on real packaging samples.",
],
supportLinks: [
{
href: "/qr-code-analytics",
title: "Commercial parent: QR Code Analytics",
description: "Best fit when packaging scans need to become a measurable post-purchase signal.",
},
{
href: "/bulk-qr-code-generator",
title: "Bulk QR Code Generator",
description: "Useful when packaging programs need many codes across SKUs, inserts, or recurring runs.",
},
{
href: "/use-cases/coupon-qr-codes",
title: "Sibling page: Coupon QR Codes",
description: "Useful when packaging scans need to trigger a measurable offer or retention prompt.",
},
],
faq: [
{
question: "What should a packaging QR code link to?",
answer: "The best destination is usually a post-purchase action such as setup help, manuals, support, registration, or a product-specific resource hub.",
},
{
question: "Can packaging QR codes be tracked?",
answer: "Yes. With a trackable QR setup you can review how packaging scans perform by product line, batch, placement, or destination.",
},
{
question: "Should packaging QR codes be dynamic?",
answer: "They should be dynamic when product documentation, app links, support flows, or promotional destinations may change after the packaging is printed.",
},
],
},
"real-estate-sign-qr-codes": {
...bySlug("real-estate-sign-qr-codes"),
eyebrow: "Real Estate",
titleSuffix: "for Listings, Brochures, and Open-House Routing",
metaDescription:
"Use real estate sign QR codes to route buyers to the current listing experience and compare sign, brochure, and open-house performance.",
intro:
"Real estate sign QR codes are strongest when listing traffic stays current even as inventory, open-house schedules, or brochure links change.",
answer:
"A real estate sign QR code should connect a passerby to the right listing, brochure, or inquiry flow today while keeping enough tracking context to compare sign performance over time.",
whenToUse: [
"You need signs, window displays, or property brochures to point to live listing information.",
"You want to compare scans from signs, flyers, open houses, or brokerage materials.",
"You need listing routes that can change after print when the property status or CTA changes.",
],
comparisonItems: [
{ label: "Listing updates", text: "Static links get stale", value: true },
{ label: "Sign performance", text: "Usually opaque", value: true },
{ label: "Property routing", text: "One fixed page", value: true },
],
howToSteps: [
"Connect each sign QR to the right listing, brochure, or lead flow instead of a generic homepage.",
"Use trackable routing when the same property appears on signs, flyers, and open-house materials.",
"Change the destination when the listing status, CTA, or follow-up flow changes without replacing printed signs.",
],
workflowTitle: "Where real estate QR systems become useful",
workflowIntro:
"Real estate print assets stay in the field while listing status and buyer next steps change. The QR setup should reflect that reality.",
workflowCards: [
{
title: "Live listing routing",
description: "Keep signs useful even if the preferred listing page, brochure path, or inquiry CTA changes after installation.",
},
{
title: "Source comparison",
description: "Compare sign traffic against property flyers, open-house materials, and office displays without merging everything into one bucket.",
},
{
title: "Lead-ready handoff",
description: "Route scanners to the current listing hub, brochure request, or showing inquiry page instead of a dead-end listing snapshot.",
},
],
checklistTitle: "Real estate sign QR checklist",
checklist: [
"Use a mobile-first listing page because most sign scans happen on phones.",
"Name tracking sources so sign, flyer, and open-house scans can be reviewed separately.",
"Update the destination when the property status or lead path changes.",
"Test scan distance and contrast on the actual sign material before production.",
],
supportLinks: [
{
href: "/qr-code-tracking",
title: "Commercial parent: QR Code Tracking",
description: "Best fit when the goal is comparing real-world property placements and scan context.",
},
{
href: "/qr-code-for-marketing-campaigns",
title: "QR Codes for Marketing Campaigns",
description: "Useful when property promotion sits inside a broader local acquisition campaign.",
},
{
href: "/use-cases/flyer-qr-codes",
title: "Sibling page: Flyer QR Codes",
description: "Useful when listing promotion depends on both sign traffic and printed collateral.",
},
],
faq: [
{
question: "What should a real estate sign QR code link to?",
answer: "It should link to the current listing experience, brochure page, or inquiry flow rather than a generic homepage or a static PDF that goes stale quickly.",
},
{
question: "Can I track real estate sign QR code scans?",
answer: "Yes. A trackable setup can help compare sign scans against other property materials such as flyers or open-house handouts.",
},
{
question: "Should real estate QR codes be dynamic?",
answer: "Yes, when listing details, CTA flows, or follow-up destinations may change while the sign remains in the field.",
},
],
},
"feedback-qr-codes": {
...bySlug("feedback-qr-codes"),
eyebrow: "Feedback",
titleSuffix: "for Reviews, In-Store Feedback, and Follow-Up Journeys",
metaDescription:
"Use feedback QR codes to capture customer responses, route high-intent users into review flows, and measure which placements get feedback.",
intro:
"Feedback QR codes work best when they remove friction from the review or response step and still let you measure which placements actually drive action.",
answer:
"A feedback QR code should make it easy for customers to leave a response in the moment while giving your team enough context to compare locations, surfaces, or follow-up performance.",
whenToUse: [
"You want table cards, receipts, packaging inserts, or in-store prompts to collect feedback fast.",
"You need a cleaner path from offline service moments into reviews or internal feedback collection.",
"You want to compare where feedback requests actually convert instead of placing the same prompt everywhere.",
],
comparisonItems: [
{ label: "Feedback routing", text: "Often generic", value: true },
{ label: "Placement reporting", text: "Weak by default", value: true },
{ label: "Review flow control", text: "Hard to tune", value: true },
],
howToSteps: [
"Place feedback QR codes where the customer can act immediately after the experience, not hours later.",
"Route the scan into the right feedback or review flow for that context.",
"Track scans and responses by placement so you know which surfaces deserve continued print inventory.",
],
workflowTitle: "Feedback QR flows that are worth measuring",
workflowIntro:
"Feedback requests perform differently depending on timing, location, and the post-scan experience. The QR flow should reflect that.",
workflowCards: [
{
title: "Moment-of-service feedback",
description: "Capture responses while the customer is still on site, at the table, or inside the post-purchase moment.",
},
{
title: "Review routing",
description: "Separate internal feedback collection from external review requests so the business controls the next step more clearly.",
},
{
title: "Placement comparison",
description: "Compare table cards, receipts, packaging inserts, and counter displays to see where customers actually respond.",
},
],
checklistTitle: "Feedback QR checklist",
checklist: [
"Ask for one simple next action after the scan instead of combining review, survey, and support in one step.",
"Place feedback prompts where the service experience is still fresh.",
"Name or tag locations so scan and response performance can be reviewed later.",
"Use a short, obvious CTA such as 'Scan to leave feedback' or 'Scan to rate your visit'.",
],
supportLinks: [
{
href: "/qr-code-tracking",
title: "Commercial parent: QR Code Tracking",
description: "Best fit when you need to compare feedback placements and understand scan context.",
},
{
href: "/blog/trackable-qr-codes",
title: "Trackable QR Codes",
description: "Support article for teams that want a measurable review or response program across multiple placements.",
},
{
href: "/use-cases/coupon-qr-codes",
title: "Sibling page: Coupon QR Codes",
description: "Useful when the same offline surfaces support both feedback collection and post-visit offers.",
},
],
faq: [
{
question: "What is a feedback QR code?",
answer: "A feedback QR code sends customers to a review, survey, or response form so they can give feedback immediately after a visit or purchase.",
},
{
question: "Can feedback QR codes be tracked?",
answer: "Yes. A trackable setup can show which placements, locations, or materials generate the most scans and responses.",
},
{
question: "Where should I place a feedback QR code?",
answer: "Place it where the customer can act right after the experience, such as on table cards, receipts, counters, packaging inserts, or post-service handouts.",
},
],
},
"payment-qr-codes": {
...bySlug("payment-qr-codes"),
eyebrow: "Payments",
titleSuffix: "for Mobile Checkout, Counter Payments, and Printed Prompts",
metaDescription:
"Use payment QR codes to route customers into a mobile payment action that stays current even when links or workflows change.",
intro:
"Payment QR codes are most useful when the printed prompt stays simple while the underlying payment destination can change with the business.",
answer:
"A payment QR code should move a scanner directly into the intended payment action on mobile without forcing the business to replace printed prompts every time the payment flow changes.",
whenToUse: [
"You use printed payment prompts on counters, tables, invoices, or leave-behind materials.",
"You need a mobile-first payment path instead of asking customers to type a long URL.",
"You want flexibility when the payment link, provider, or landing flow changes over time.",
],
comparisonItems: [
{ label: "Payment destination", text: "Fixed once printed", value: true },
{ label: "Provider changes", text: "Reprint required", value: true },
{ label: "Post-scan routing", text: "Limited", value: true },
],
howToSteps: [
"Decide which payment action the code should trigger: direct payment, checkout page, invoice page, or service deposit.",
"Generate one QR per real payment context instead of one generic payment code for everything.",
"Use a destination that can be updated when your payment provider or checkout flow changes.",
],
workflowTitle: "Payment QR workflows that stay practical after print",
workflowIntro:
"Payment prompts live on physical surfaces longer than the payment links behind them. The QR workflow should absorb that change instead of forcing reprints.",
workflowCards: [
{
title: "Counter and table payments",
description: "Use printed QR prompts to move a customer into a fast mobile payment step without manual URL entry.",
},
{
title: "Invoice and leave-behind flows",
description: "Attach payment actions to printed materials that may remain in circulation after a provider or link update.",
},
{
title: "Context-specific routing",
description: "Send different payment scenarios to the right checkout or follow-up path instead of one catch-all destination.",
},
],
checklistTitle: "Payment QR checklist",
checklist: [
"Make the scan CTA specific so users know they are opening a payment action.",
"Use a mobile-first checkout or payment screen.",
"Keep one QR per payment context when the follow-up steps differ.",
"Update the destination if provider links or invoice flows change after print.",
],
supportLinks: [
{
href: "/dynamic-qr-code-generator",
title: "Commercial parent: Dynamic QR Code Generator",
description: "Best fit when the printed payment prompt must survive future destination changes.",
},
{
href: "/tools/paypal-qr-code",
title: "PayPal QR Code tool",
description: "Useful for direct payment-oriented workflows when PayPal is the intended post-scan action.",
},
{
href: "/use-cases/restaurant-menu-qr-codes",
title: "Sibling page: Restaurant Menu QR Codes",
description: "Useful when table cards combine service information and a later payment or ordering action.",
},
],
faq: [
{
question: "What should a payment QR code link to?",
answer: "It should link to the actual mobile payment action you want the user to take, such as a checkout page, invoice page, or direct payment destination.",
},
{
question: "Should payment QR codes be dynamic?",
answer: "Yes, when the payment destination, provider, or checkout flow may change after the printed code is already in use.",
},
{
question: "Where do payment QR codes work best?",
answer: "They work best on printed surfaces where a fast mobile payment step is valuable, such as counters, invoices, tables, service documents, or leave-behind materials.",
},
],
},
"coupon-qr-codes": {
...bySlug("coupon-qr-codes"),
eyebrow: "Offers",
titleSuffix: "for Measurable Discounts, Redemptions, and Local Promotions",
metaDescription:
"Use coupon QR codes to connect printed offers with measurable scans, current discount pages, and cleaner redemption reporting.",
intro:
"Coupon QR codes are strongest when the discount path stays current and your team can see which print placements actually generate redemptions.",
answer:
"A coupon QR code should connect one printed offer to a landing or redemption flow you can update later while preserving enough tracking context to compare placements and promotion waves.",
whenToUse: [
"You run discounts on flyers, receipts, inserts, posters, or local print campaigns.",
"You want to compare which printed offer placements drive scans or redemptions.",
"You need the offer destination to stay current even if the promotion changes after print.",
],
comparisonItems: [
{ label: "Offer changes", text: "Static links go stale", value: true },
{ label: "Redemption visibility", text: "Often weak", value: true },
{ label: "Placement comparison", text: "Usually manual", value: true },
],
howToSteps: [
"Create one coupon QR flow per actual offer or placement group instead of mixing promotions together.",
"Use a destination or coupon page that can change after distribution if the offer window shifts.",
"Review scan and redemption context by flyer, receipt, package insert, or local placement before scaling the next campaign.",
],
workflowTitle: "Coupon QR systems that improve the next campaign",
workflowIntro:
"Printed offers are only useful if the path behind them stays live and the results can be reviewed later. A coupon QR should support both.",
workflowCards: [
{
title: "Offer routing after print",
description: "Keep the same printed discount prompt alive while the landing page, code, or campaign framing changes.",
},
{
title: "Placement reporting",
description: "Compare where coupons get scanned or redeemed so posters, flyers, inserts, and receipts stop being one blended source.",
},
{
title: "Redemption-focused follow-up",
description: "Route the scan into a path that makes redemption easy instead of forcing the user to search for the offer again.",
},
],
checklistTitle: "Coupon QR checklist",
checklist: [
"Write the offer clearly on the printed asset so the QR code reinforces one promise.",
"Use distinct tracking for major placements or campaign waves.",
"Keep the redemption page or coupon path mobile-friendly.",
"Update the destination when the offer changes instead of leaving dead promotions in circulation.",
],
supportLinks: [
{
href: "/qr-code-tracking",
title: "Commercial parent: QR Code Tracking",
description: "Best fit when the value comes from comparing placements and measuring offer performance.",
},
{
href: "/blog/trackable-qr-codes",
title: "Trackable QR Codes",
description: "Support article for teams that want a more measurable coupon or discount program.",
},
{
href: "/use-cases/flyer-qr-codes",
title: "Sibling page: Flyer QR Codes",
description: "Useful when the coupon is part of a measurable flyer or local promotion program.",
},
],
faq: [
{
question: "What is a coupon QR code?",
answer: "A coupon QR code sends users to an offer or redemption page so the discount can be claimed without typing a URL or code manually.",
},
{
question: "Can coupon QR codes be tracked?",
answer: "Yes. A trackable setup helps compare scans and coupon performance across placements such as flyers, posters, inserts, or receipts.",
},
{
question: "Should a coupon QR code be dynamic?",
answer: "Yes, when the promotion, landing page, or redemption flow may change while the printed asset is still in circulation.",
},
],
},
};
export function getUseCasePage(slug: string): UseCasePageContent | undefined {

View File

@ -32,10 +32,11 @@ export function middleware(req: NextRequest) {
'/features',
// '/guide', // Redirected to /learn/*
'/qr-code-erstellen',
'/dynamic-qr-code-generator',
'/bulk-qr-code-generator',
'/qr-code-tracking',
'/reprint-calculator',
'/dynamic-qr-code-generator',
'/bulk-qr-code-generator',
'/qr-code-tracking',
'/qr-code-analytics',
'/reprint-calculator',
'/barcode-generator',
'/custom-qr-code-generator',
'/manage-qr-codes',
@ -51,6 +52,12 @@ export function middleware(req: NextRequest) {
'/press',
'/testimonials',
'/qr-code-for-marketing-campaigns',
'/use-cases/flyer-qr-codes',
'/use-cases/packaging-qr-codes',
'/use-cases/real-estate-sign-qr-codes',
'/use-cases/feedback-qr-codes',
'/use-cases/payment-qr-codes',
'/use-cases/coupon-qr-codes',
];
// Check if path is public

View File

@ -0,0 +1,272 @@
# 30-Day X/Twitter Content Plan for QR Master
Use this as a `30-day X/Twitter content plan` for a founder-led QR Master account. It is written in English and optimized for reach first, with product relevance built in.
## Positioning for the Month
`Dynamic QR codes for measurable offline marketing, without creepy tracking.`
## Audience Focus
Primary audience for Days 1-15:
`Restaurants / hospitality`
Secondary audience for Days 16-30:
`Agencies / offline marketers / retail operators`
## CTA Rule for the Whole Month
- Most posts: `Reply with a keyword`, `follow for more`, or `DM me`
- Only light link usage
- Put direct product CTA mainly in replies, profile, and pinned post
## 30-Day Plan
### Day 1
**Post type:** Founder positioning post
**Hook:** `Most QR codes are dead the moment they get printed.`
**Angle:** Static QR codes create reprint costs and broken customer journeys.
**CTA:** `If you run offline marketing, follow this account. Im breaking down how to fix it.`
### Day 2
**Post type:** Short insight post
**Hook:** `A restaurant menu should not require a reprint every time one dish changes.`
**Angle:** Dynamic QR codes for menus and specials.
**CTA:** `Reply “menu” if you want me to post the exact setup.`
### Day 3
**Post type:** Teardown
**Hook:** `3 mistakes I see on restaurant QR menus all the time:`
**Angle:** Bad placement, no fallback page, no analytics.
**CTA:** `Want me to roast your menu QR? Reply with a screenshot.`
### Day 4
**Post type:** Thread
**Hook:** `How restaurants can update menus without reprinting tables, flyers, or window signs:`
**Angle:** 5-step workflow using one dynamic QR.
**CTA:** `I can turn this into a checklist if people want it.`
### Day 5
**Post type:** Contrarian post
**Hook:** `Unpopular opinion: “free QR code generators” are expensive.`
**Angle:** Hidden cost is reprints, lost scans, no attribution.
**CTA:** `Agree or disagree?`
### Day 6
**Post type:** Demo video
**Hook:** `Change the destination after print. Thats the whole game.`
**Angle:** Quick screen recording showing edit-after-print.
**CTA:** `DM me “edit” and Ill send the workflow.`
### Day 7
**Post type:** Founder story
**Hook:** `We started building QR Master because most QR tools felt like toys.`
**Angle:** Needed analytics, bulk creation, privacy-first tracking.
**CTA:** `Whats one thing you hate about current QR tools?`
### Day 8
**Post type:** Pain-to-fix post
**Hook:** `If your flyer has a QR code but no tracking, youre guessing.`
**Angle:** Offline campaigns need measurable scans.
**CTA:** `Reply “track” if you want a simple attribution template.`
### Day 9
**Post type:** Restaurant-specific post
**Hook:** `Todays special changes. Your printed QR shouldnt.`
**Angle:** Daily menu operations.
**CTA:** `Restaurant owners: how often do you update menus?`
### Day 10
**Post type:** Roast / audit
**Hook:** `This QR code placement is killing conversions.`
**Angle:** Explain why low-visibility placements fail.
**CTA:** `Send me your flyer/menu/poster and Ill break it down.`
### Day 11
**Post type:** Thread
**Hook:** `5 QR code mistakes that make restaurant marketing look cheap:`
**Angle:** Visual clutter, dead links, bad landing pages, no tracking, wrong CTA.
**CTA:** `Ill post 5 fixes tomorrow if this gets traction.`
### Day 12
**Post type:** Build in public
**Hook:** `One thing founders underestimate: people dont want “a QR code.” They want a workflow.`
**Angle:** Product insight from building.
**CTA:** `What simple tool became critical in your business?`
### Day 13
**Post type:** Short proof post
**Hook:** `One QR code. Multiple seasonal campaigns. Zero reprints.`
**Angle:** Reuse same printed asset with changing destination.
**CTA:** `This is one of the biggest underrated offline growth hacks.`
### Day 14
**Post type:** Demo video
**Hook:** `From printed table card to measurable scan funnel in under 30 seconds:`
**Angle:** Show QR creation + analytics preview.
**CTA:** `If you want more product breakdowns, follow.`
### Day 15
**Post type:** Summary / recap
**Hook:** `The biggest restaurant QR lesson so far:`
**Angle:** Most businesses dont need more print, they need more flexibility.
**CTA:** `Next week Im switching to agencies and offline marketers.`
### Day 16
**Post type:** Agency-focused post
**Hook:** `If your agency runs flyer or poster campaigns without QR attribution, youre underreporting impact.`
**Angle:** Agencies need scan data to prove ROI.
**CTA:** `Reply “agency” if you want my offline attribution framework.`
### Day 17
**Post type:** Contrarian post
**Hook:** `The problem is not the QR code. The problem is the dead destination behind it.`
**Angle:** Static link is the failure point.
**CTA:** `This is where most campaigns quietly lose money.`
### Day 18
**Post type:** Thread
**Hook:** `How to make offline campaigns actually measurable:`
**Angle:** QR + UTM + landing page + analytics naming structure.
**CTA:** `I can turn this into a swipe file.`
### Day 19
**Post type:** Audit post
**Hook:** `3 reasons most poster QR campaigns dont convert:`
**Angle:** Weak CTA, poor mobile page, no tracking structure.
**CTA:** `Want a poster teardown series?`
### Day 20
**Post type:** Demo video
**Hook:** `Bulk-create hundreds of QR codes from a spreadsheet.`
**Angle:** Show CSV/Excel workflow for agencies or retail.
**CTA:** `DM me “bulk” if that would save your team time.`
### Day 21
**Post type:** Founder hot take
**Hook:** `“Just put a QR code on it” is bad marketing advice.`
**Angle:** QR is distribution, not strategy.
**CTA:** `What matters more: placement, offer, or landing page?`
### Day 22
**Post type:** Mini case format
**Hook:** `Campaign idea: one printed asset, three different destinations over 30 days.`
**Angle:** Explain how one QR can support multiple campaign phases.
**CTA:** `This is why dynamic matters more than design.`
### Day 23
**Post type:** Thread
**Hook:** `How Id structure QR tracking for an agency campaign with flyers, packaging, and in-store signage:`
**Angle:** Naming conventions, attribution logic, reporting.
**CTA:** `If useful, Ill post the naming template.`
### Day 24
**Post type:** Privacy wedge post
**Hook:** `You can measure scans without turning people into surveillance data.`
**Angle:** Privacy-first analytics as a business advantage.
**CTA:** `Too many teams think analytics has to mean creepy.`
### Day 25
**Post type:** Teardown
**Hook:** `This flyer has a QR code. But it still wont tell you what worked.`
**Angle:** Missing attribution structure.
**CTA:** `Reply with “audit” and Ill post a fixed version.`
### Day 26
**Post type:** Retail / packaging post
**Hook:** `Packaging QR codes get interesting when you can change the destination later.`
**Angle:** Product updates, campaigns, support pages, seasonal promos.
**CTA:** `Retail operators: are you using QR for support, promo, or repeat purchase?`
### Day 27
**Post type:** Build in public
**Hook:** `One thing we keep seeing: people buy QR tools for “generation” and stay for “management.”`
**Angle:** Product-market insight.
**CTA:** `That distinction matters more than most founders think.`
### Day 28
**Post type:** Demo video
**Hook:** `Heres what “measurable offline workflow” actually looks like in practice:`
**Angle:** Create, edit, track, compare placements.
**CTA:** `If this kind of content is useful, Ill make it a weekly series.`
### Day 29
**Post type:** Hero thread
**Hook:** `Most offline marketing teams dont have a traffic problem. They have a measurement problem.`
**Angle:** Big thesis thread connecting restaurants, agencies, retail, and dynamic QR logic.
**CTA:** `If you work in offline marketing, this is the framework.`
### Day 30
**Post type:** Month-end recap + soft CTA
**Hook:** `30 days of talking to people about QR workflows taught me this:`
**Angle:** Summarize 5 strongest lessons from the month.
**CTA:** `If you want, next Ill publish the full playbook: hooks, setup, and attribution templates.`
## Weekly Cadence
- `Mon`: strong opinion or positioning
- `Tue`: practical educational post
- `Wed`: teardown or audit
- `Thu`: thread
- `Fri`: product proof or demo
- `Sat`: founder insight / build in public
- `Sun`: recap or lighter conversation post
## Content Mix
- `8 threads`
- `6 teardown/audit posts`
- `5 demo videos`
- `6 short contrarian/value posts`
- `5 founder/build-in-public posts`
## Reply Strategy
Every day, add:
- `10-15 replies` to founders, marketers, restaurant-tech, local business, retail ops, and agency accounts
- Focus on posts about: offline marketing, menus, customer journeys, attribution, retail campaigns, print, local growth
- Use replies to seed your core themes:
- reprint cost
- edit after print
- measurable offline
- privacy-first analytics
- bulk workflows
## Optional Next Step
If needed, this can be expanded into:
1. fully written tweets for all 30 days
2. 8 full threads written out
3. a Notion-style content calendar with posting times and CTAs