search console SEO ableitungen

This commit is contained in:
2026-03-23 19:01:52 -05:00
parent d47108d27c
commit e6b19e7a1c
150 changed files with 26257 additions and 25909 deletions

View File

@@ -1,145 +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(/ /g, ' ')
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/'/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',
},
});
}
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',
},
});
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,243 +1,243 @@
import React from 'react';
import type { Metadata } from 'next';
import Link from 'next/link';
import SeoJsonLd from '@/components/SeoJsonLd';
import { faqPageSchema } from '@/lib/schema';
import { Card, CardContent } from '@/components/ui/Card';
import { ObfuscatedMailto } from '@/components/ui/ObfuscatedMailto';
function truncateAtWord(text: string, maxLength: number): string {
if (text.length <= maxLength) return text;
const truncated = text.slice(0, maxLength);
const lastSpace = truncated.lastIndexOf(' ');
return lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated;
}
export async function generateMetadata(): Promise<Metadata> {
const title = truncateAtWord('QR Master FAQ: Dynamic, Tracking, Bulk, and Print', 60);
const description = truncateAtWord(
'Answers about dynamic QR codes, scan tracking, privacy, bulk creation, and print setup.',
160
);
return {
title,
description,
alternates: {
canonical: 'https://www.qrmaster.net/faq',
languages: {
'x-default': 'https://www.qrmaster.net/faq',
en: 'https://www.qrmaster.net/faq',
},
},
openGraph: {
title,
description,
url: 'https://www.qrmaster.net/faq',
type: 'website',
images: [
{
url: 'https://www.qrmaster.net/og-image.png',
width: 1200,
height: 630,
alt: 'QR Master FAQ',
},
],
},
twitter: {
title,
description,
},
};
}
type FAQItemWithRichText = {
question: string;
answer: string;
answerRich?: React.ReactNode;
};
const faqs: FAQItemWithRichText[] = [
{
question: 'What is a dynamic QR code?',
answer:
'A dynamic QR code points to a redirect URL, so you can change the final destination later without replacing the printed QR image.',
answerRich: (
<>
A dynamic QR code points to a redirect URL, so you can change the final destination later without replacing the printed QR image.
<br />
<br />
<strong>Why teams use it:</strong>
<ul className="mt-2 list-disc space-y-1 pl-5">
<li>Update the destination after print</li>
<li>Review scan analytics later</li>
<li>Keep one printed QR in use across changing campaigns or content</li>
</ul>
</>
),
},
{
question: 'How do I track QR scans?',
answer:
'QR Master tracks scans through the dynamic QR redirect step. The analytics views can report time, device, location context, and total or unique scan activity.',
answerRich: (
<>
QR Master tracks scans through the dynamic QR redirect step.
<br />
<br />
<strong>Current analytics context:</strong>
<ul className="mt-2 list-disc space-y-1 pl-5">
<li>Total and unique scan reporting</li>
<li>Device type</li>
<li>Location context</li>
<li>Time-based scan activity</li>
</ul>
<br />
<Link href="/qr-code-tracking" className="font-medium text-blue-600 hover:underline">
Learn more about tracking
</Link>
</>
),
},
{
question: 'What security measures are in place?',
answer:
'QR Master uses HTTPS/TLS, CSRF protection for relevant write actions, and rate limiting on API routes.',
answerRich: (
<>
QR Master uses standard protective controls that are visible in the current codebase.
<br />
<br />
<strong>Security-related controls:</strong>
<ul className="mt-2 list-disc space-y-1 pl-5">
<li>HTTPS/TLS encryption for all connections</li>
<li>CSRF protection for relevant write actions</li>
<li>Rate limiting on API routes</li>
</ul>
</>
),
},
{
question: 'How does bulk QR creation work today?',
answer:
'QR Master currently supports bulk QR creation through spreadsheet upload in the Business plan. The flow accepts CSV, XLS, and XLSX files, supports up to 1,000 rows per upload, and generates static QR codes.',
answerRich: (
<>
QR Master currently supports bulk QR creation through spreadsheet upload in the Business plan.
<br />
<br />
<strong>Current bulk flow facts:</strong>
<ul className="mt-2 list-disc space-y-1 pl-5">
<li>CSV, XLS, and XLSX uploads are supported</li>
<li>Up to 1,000 rows per upload</li>
<li>Output is static QR codes, not dynamic tracking batches</li>
</ul>
<br />
<Link href="/bulk-qr-code-generator" className="font-medium text-blue-600 hover:underline">
See the bulk QR workflow
</Link>
</>
),
},
{
question: 'What are the best practices for printing QR codes?',
answer:
'For reliable scanning, keep the QR code at least 2x2 cm for close-range use, maintain strong contrast, leave a quiet zone around the code, and use SVG or a high-resolution PNG for output.',
answerRich: (
<>
For reliable scanning, follow these print-first basics:
<br />
<br />
<ul className="mt-2 list-disc space-y-1 pl-5">
<li>Minimum size around 2x2 cm for close-range scans</li>
<li>Dark foreground on a light background</li>
<li>Leave a quiet zone around the QR code</li>
<li>Use SVG or a high-resolution PNG depending on the print workflow</li>
</ul>
</>
),
},
{
question: 'Is the service privacy-conscious?',
answer:
'QR Master minimizes scanner data collection. Privacy-related measures visible in the product context include hashed or anonymized IP handling and no scanner PII storage.',
answerRich: (
<>
QR Master is built around minimal scanner data collection.
<br />
<br />
<strong>Privacy-related measures:</strong>
<ul className="mt-2 list-disc space-y-1 pl-5">
<li>IP addresses are anonymized or hashed</li>
<li>No scanner PII storage</li>
</ul>
<br />
<Link href="/privacy" className="font-medium text-blue-600 hover:underline">
Read the privacy policy
</Link>
</>
),
},
{
question: 'What is the difference between static and dynamic QR codes?',
answer:
'Static QR codes store the destination directly in the image and stay fixed. Dynamic QR codes route through QR Master so the destination can be changed later and scan analytics can be reviewed.',
answerRich: (
<>
Static QR codes store the destination directly in the image and stay fixed.
Dynamic QR codes route through QR Master so the destination can be changed later and scan analytics can be reviewed.
<br />
<br />
<Link href="/dynamic-qr-code-generator" className="font-medium text-blue-600 hover:underline">
Create a dynamic QR code
</Link>
</>
),
},
];
export default function FAQPage() {
return (
<>
<SeoJsonLd data={faqPageSchema(faqs.map(({ question, answer }) => ({ question, answer })))} />
<div className="bg-gradient-to-b from-gray-50 to-white py-20">
<div className="container mx-auto px-4">
<div className="mx-auto max-w-4xl">
<div className="mb-16 text-center">
<h1 className="mb-6 text-4xl font-bold text-gray-900 lg:text-5xl">
Frequently Asked Questions
</h1>
<p className="mb-4 text-xl text-gray-600">
Answers about dynamic QR codes, scan tracking, privacy, bulk creation, and print setup.
</p>
<p className="text-sm text-gray-500">Last updated: March 12, 2026</p>
</div>
<div className="space-y-6">
{faqs.map((faq) => (
<Card key={faq.question} className="border-l-4 border-blue-500">
<CardContent className="p-8">
<h2 className="mb-4 text-2xl font-semibold text-gray-900">{faq.question}</h2>
<div className="text-lg leading-relaxed text-gray-700">{faq.answerRich || faq.answer}</div>
</CardContent>
</Card>
))}
</div>
<div className="mt-16 rounded-r-lg border-l-4 border-blue-500 bg-blue-50 p-8">
<h2 className="mb-4 text-2xl font-bold text-gray-900">Still have questions?</h2>
<p className="text-lg leading-relaxed text-gray-700">
Our support team is here to help. Contact us at{' '}
<ObfuscatedMailto
email="support@qrmaster.net"
className="font-semibold text-blue-600 hover:text-blue-700"
/>{' '}
and include the workflow you are trying to build.
</p>
</div>
</div>
</div>
</div>
</>
);
}
import React from 'react';
import type { Metadata } from 'next';
import Link from 'next/link';
import SeoJsonLd from '@/components/SeoJsonLd';
import { faqPageSchema } from '@/lib/schema';
import { Card, CardContent } from '@/components/ui/Card';
import { ObfuscatedMailto } from '@/components/ui/ObfuscatedMailto';
function truncateAtWord(text: string, maxLength: number): string {
if (text.length <= maxLength) return text;
const truncated = text.slice(0, maxLength);
const lastSpace = truncated.lastIndexOf(' ');
return lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated;
}
export async function generateMetadata(): Promise<Metadata> {
const title = truncateAtWord('QR Master FAQ: Dynamic, Tracking, Bulk, and Print', 60);
const description = truncateAtWord(
'Answers about dynamic QR codes, scan tracking, privacy, bulk creation, and print setup.',
160
);
return {
title,
description,
alternates: {
canonical: 'https://www.qrmaster.net/faq',
languages: {
'x-default': 'https://www.qrmaster.net/faq',
en: 'https://www.qrmaster.net/faq',
},
},
openGraph: {
title,
description,
url: 'https://www.qrmaster.net/faq',
type: 'website',
images: [
{
url: 'https://www.qrmaster.net/og-image.png',
width: 1200,
height: 630,
alt: 'QR Master FAQ',
},
],
},
twitter: {
title,
description,
},
};
}
type FAQItemWithRichText = {
question: string;
answer: string;
answerRich?: React.ReactNode;
};
const faqs: FAQItemWithRichText[] = [
{
question: 'What is a dynamic QR code?',
answer:
'A dynamic QR code points to a redirect URL, so you can change the final destination later without replacing the printed QR image.',
answerRich: (
<>
A dynamic QR code points to a redirect URL, so you can change the final destination later without replacing the printed QR image.
<br />
<br />
<strong>Why teams use it:</strong>
<ul className="mt-2 list-disc space-y-1 pl-5">
<li>Update the destination after print</li>
<li>Review scan analytics later</li>
<li>Keep one printed QR in use across changing campaigns or content</li>
</ul>
</>
),
},
{
question: 'How do I track QR scans?',
answer:
'QR Master tracks scans through the dynamic QR redirect step. The analytics views can report time, device, location context, and total or unique scan activity.',
answerRich: (
<>
QR Master tracks scans through the dynamic QR redirect step.
<br />
<br />
<strong>Current analytics context:</strong>
<ul className="mt-2 list-disc space-y-1 pl-5">
<li>Total and unique scan reporting</li>
<li>Device type</li>
<li>Location context</li>
<li>Time-based scan activity</li>
</ul>
<br />
<Link href="/qr-code-tracking" className="font-medium text-blue-600 hover:underline">
Learn more about tracking
</Link>
</>
),
},
{
question: 'What security measures are in place?',
answer:
'QR Master uses HTTPS/TLS, CSRF protection for relevant write actions, and rate limiting on API routes.',
answerRich: (
<>
QR Master uses standard protective controls that are visible in the current codebase.
<br />
<br />
<strong>Security-related controls:</strong>
<ul className="mt-2 list-disc space-y-1 pl-5">
<li>HTTPS/TLS encryption for all connections</li>
<li>CSRF protection for relevant write actions</li>
<li>Rate limiting on API routes</li>
</ul>
</>
),
},
{
question: 'How does bulk QR creation work today?',
answer:
'QR Master currently supports bulk QR creation through spreadsheet upload in the Business plan. The flow accepts CSV, XLS, and XLSX files, supports up to 1,000 rows per upload, and generates static QR codes.',
answerRich: (
<>
QR Master currently supports bulk QR creation through spreadsheet upload in the Business plan.
<br />
<br />
<strong>Current bulk flow facts:</strong>
<ul className="mt-2 list-disc space-y-1 pl-5">
<li>CSV, XLS, and XLSX uploads are supported</li>
<li>Up to 1,000 rows per upload</li>
<li>Output is static QR codes, not dynamic tracking batches</li>
</ul>
<br />
<Link href="/bulk-qr-code-generator" className="font-medium text-blue-600 hover:underline">
See the bulk QR workflow
</Link>
</>
),
},
{
question: 'What are the best practices for printing QR codes?',
answer:
'For reliable scanning, keep the QR code at least 2x2 cm for close-range use, maintain strong contrast, leave a quiet zone around the code, and use SVG or a high-resolution PNG for output.',
answerRich: (
<>
For reliable scanning, follow these print-first basics:
<br />
<br />
<ul className="mt-2 list-disc space-y-1 pl-5">
<li>Minimum size around 2x2 cm for close-range scans</li>
<li>Dark foreground on a light background</li>
<li>Leave a quiet zone around the QR code</li>
<li>Use SVG or a high-resolution PNG depending on the print workflow</li>
</ul>
</>
),
},
{
question: 'Is the service privacy-conscious?',
answer:
'QR Master minimizes scanner data collection. Privacy-related measures visible in the product context include hashed or anonymized IP handling and no scanner PII storage.',
answerRich: (
<>
QR Master is built around minimal scanner data collection.
<br />
<br />
<strong>Privacy-related measures:</strong>
<ul className="mt-2 list-disc space-y-1 pl-5">
<li>IP addresses are anonymized or hashed</li>
<li>No scanner PII storage</li>
</ul>
<br />
<Link href="/privacy" className="font-medium text-blue-600 hover:underline">
Read the privacy policy
</Link>
</>
),
},
{
question: 'What is the difference between static and dynamic QR codes?',
answer:
'Static QR codes store the destination directly in the image and stay fixed. Dynamic QR codes route through QR Master so the destination can be changed later and scan analytics can be reviewed.',
answerRich: (
<>
Static QR codes store the destination directly in the image and stay fixed.
Dynamic QR codes route through QR Master so the destination can be changed later and scan analytics can be reviewed.
<br />
<br />
<Link href="/dynamic-qr-code-generator" className="font-medium text-blue-600 hover:underline">
Create a dynamic QR code
</Link>
</>
),
},
];
export default function FAQPage() {
return (
<>
<SeoJsonLd data={faqPageSchema(faqs.map(({ question, answer }) => ({ question, answer })))} />
<div className="bg-gradient-to-b from-gray-50 to-white py-20">
<div className="container mx-auto px-4">
<div className="mx-auto max-w-4xl">
<div className="mb-16 text-center">
<h1 className="mb-6 text-4xl font-bold text-gray-900 lg:text-5xl">
Frequently Asked Questions
</h1>
<p className="mb-4 text-xl text-gray-600">
Answers about dynamic QR codes, scan tracking, privacy, bulk creation, and print setup.
</p>
<p className="text-sm text-gray-500">Last updated: March 12, 2026</p>
</div>
<div className="space-y-6">
{faqs.map((faq) => (
<Card key={faq.question} className="border-l-4 border-blue-500">
<CardContent className="p-8">
<h2 className="mb-4 text-2xl font-semibold text-gray-900">{faq.question}</h2>
<div className="text-lg leading-relaxed text-gray-700">{faq.answerRich || faq.answer}</div>
</CardContent>
</Card>
))}
</div>
<div className="mt-16 rounded-r-lg border-l-4 border-blue-500 bg-blue-50 p-8">
<h2 className="mb-4 text-2xl font-bold text-gray-900">Still have questions?</h2>
<p className="text-lg leading-relaxed text-gray-700">
Our support team is here to help. Contact us at{' '}
<ObfuscatedMailto
email="support@qrmaster.net"
className="font-semibold text-blue-600 hover:text-blue-700"
/>{' '}
and include the workflow you are trying to build.
</p>
</div>
</div>
</div>
</div>
</>
);
}

View File

@@ -1,389 +1,389 @@
import React from 'react';
import type { Metadata } from 'next';
import Link from 'next/link';
import { Button } from '@/components/ui/Button';
import { Card } from '@/components/ui/Card';
import SeoJsonLd from '@/components/SeoJsonLd';
import Breadcrumbs, { BreadcrumbItem } from '@/components/Breadcrumbs';
import { breadcrumbSchema, faqPageSchema } from '@/lib/schema';
import { AnswerFirstBlock } from '@/components/marketing/AnswerFirstBlock';
import { FAQSection } from '@/components/aeo/FAQSection';
export const metadata: Metadata = {
title: {
absolute: 'Manage QR Codes - Dashboard, Edits, and Analytics',
},
description:
'Manage QR codes in one dashboard. Review active codes, edit dynamic destinations, see scan totals and unique scans, and work within current Free, Pro, or Business limits.',
keywords: [
'manage qr codes',
'qr code dashboard',
'edit dynamic qr codes',
'qr code analytics dashboard',
'qr code management',
],
alternates: {
canonical: 'https://www.qrmaster.net/manage-qr-codes',
languages: {
'x-default': 'https://www.qrmaster.net/manage-qr-codes',
en: 'https://www.qrmaster.net/manage-qr-codes',
},
},
openGraph: {
title: 'Manage QR Codes - Dashboard, Edits, and Analytics',
description:
'Use one dashboard to review QR codes, edit dynamic destinations, and check scan totals and unique scans.',
url: 'https://www.qrmaster.net/manage-qr-codes',
type: 'website',
images: [
{
url: '/images/og/og-manage-qr-codes.png',
width: 1200,
height: 630,
},
],
},
twitter: {
title: 'Manage QR Codes - Dashboard, Edits, and Analytics',
description:
'Use one dashboard to review QR codes, edit dynamic destinations, and check scan totals and unique scans.',
},
};
const verifiedCapabilities = [
{
title: 'Central dashboard',
description:
'The dashboard lists your QR codes in one place instead of forcing you to manage separate files or links manually.',
},
{
title: 'Dynamic destination edits',
description:
'Dynamic QR codes can be edited after print. Static QR codes remain fixed.',
},
{
title: 'Scan reporting',
description:
'The current dashboard reports total scans, active codes, and unique scans, with analytics pages adding more context.',
},
{
title: 'Plan-based limits',
description:
'Free includes 3 dynamic QR codes, Pro includes 50, and Business includes 500. Static QR codes remain unlimited.',
},
{
title: 'Tags and status',
description:
'QR code records support tags and active status, which helps keep batches and single-code workflows easier to review.',
},
{
title: 'Download and delete actions',
description:
'Each QR code card supports view, download, edit for dynamic QR codes, and delete actions from the dashboard surface.',
},
];
const operationalUseCases = [
{
title: 'Marketing campaigns',
description:
'Review active dynamic QR codes, compare scan totals, and update destinations when campaigns or landing pages change.',
points: ['One list of active codes', 'Scan totals and unique scans', 'Edit dynamic destinations'],
},
{
title: 'Restaurants and hospitality',
description:
'Keep menu or table-card QR codes current from the dashboard instead of reprinting every time the destination changes.',
points: ['Update menu destinations', 'Monitor scan activity', 'Keep print assets in use longer'],
},
{
title: 'Product and packaging workflows',
description:
'Track which QR codes are active, save batches to the dashboard, and separate static bulk output from dynamic campaign codes.',
points: ['Save generated QR codes', 'Review active status', 'Manage static and dynamic codes separately'],
},
{
title: 'Small team or solo workflows',
description:
'Use one account to keep QR code creation, edits, downloads, and analytics in one operational place.',
points: ['Single dashboard view', 'No spreadsheet-only workflow', 'Clear plan limits'],
},
];
const faqItems = [
{
question: 'What does it mean to manage QR codes?',
answer:
'In QR Master, managing QR codes means using one dashboard to review your QR codes, edit dynamic destinations, download files, and check scan activity instead of tracking everything manually.',
},
{
question: 'Can I edit a QR code after printing it?',
answer:
'Yes, if it is a dynamic QR code. Static QR codes stay fixed after creation.',
},
{
question: 'How many dynamic QR codes can I manage?',
answer:
'Free includes 3 dynamic QR codes, Pro includes 50, and Business includes 500. Static QR codes are unlimited.',
},
{
question: 'What analytics are visible today?',
answer:
'The current dashboard shows total scans, active QR codes, and unique scans. Additional analytics views add more scan context such as time, device, and location.',
},
{
question: 'Does the current product include team roles or API-based QR management?',
answer:
'This page only reflects the verified current surface: dashboard management, dynamic edits, analytics, downloads, tags, and plan limits. It does not claim team roles or public API-based QR management as current verified capabilities.',
},
];
const softwareSchema = {
'@context': 'https://schema.org',
'@type': 'SoftwareApplication',
'@id': 'https://www.qrmaster.net/manage-qr-codes#software',
name: 'QR Master - QR Code Management Dashboard',
applicationCategory: 'BusinessApplication',
offers: {
'@type': 'AggregateOffer',
lowPrice: '0',
highPrice: '29',
priceCurrency: 'EUR',
},
featureList: [
'Central QR code dashboard',
'Edit dynamic QR code destinations',
'Review total and unique scan counts',
'Download QR codes as PNG or SVG',
'Tag QR code records and review active status',
'Manage current plan limits for dynamic QR codes',
],
};
const breadcrumbItems: BreadcrumbItem[] = [
{ name: 'Home', url: '/' },
{ name: 'Manage QR Codes', url: '/manage-qr-codes' },
];
export default function ManageQRCodesPage() {
return (
<>
<SeoJsonLd
data={[
softwareSchema,
breadcrumbSchema(breadcrumbItems),
faqPageSchema(faqItems),
]}
/>
<div className="min-h-screen bg-white">
<section className="relative overflow-hidden bg-gradient-to-br from-green-50 via-white to-blue-50 py-20">
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<Breadcrumbs items={breadcrumbItems} />
<div className="mt-8 grid items-center gap-12 lg:grid-cols-2">
<div className="space-y-8">
<div className="inline-flex items-center rounded-full bg-green-100 px-4 py-2 text-sm font-semibold text-green-800">
Dashboard-first QR management
</div>
<div className="space-y-5">
<h1 className="text-5xl font-bold leading-tight text-gray-900 lg:text-6xl">
Manage QR Codes from one dashboard
</h1>
<p className="text-xl leading-relaxed text-gray-600">
Review active QR codes, edit dynamic destinations, download files, and
monitor scan totals from one place instead of managing printed QR workflows manually.
</p>
</div>
<div className="space-y-3">
{[
'See QR codes in one dashboard',
'Edit dynamic destinations after print',
'Review total scans, active codes, and unique scans',
'Work within the current Free, Pro, and Business dynamic QR limits',
].map((feature) => (
<div key={feature} className="flex items-center gap-3">
<div className="flex h-5 w-5 items-center justify-center rounded-full bg-green-500">
<svg className="h-3 w-3 text-white" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clipRule="evenodd"
/>
</svg>
</div>
<span className="text-gray-700">{feature}</span>
</div>
))}
</div>
<div className="flex flex-col gap-4 sm:flex-row">
<Link href="/signup">
<Button size="lg" className="w-full px-8 py-4 text-lg sm:w-auto">
Get Started Free
</Button>
</Link>
<Link href="/pricing">
<Button variant="outline" size="lg" className="w-full px-8 py-4 text-lg sm:w-auto">
View Pricing
</Button>
</Link>
</div>
</div>
<div className="relative">
<Card className="p-6 shadow-2xl">
<h3 className="mb-4 text-lg font-semibold">Dashboard snapshot</h3>
<div className="space-y-3">
<div className="rounded-lg border border-blue-200 bg-blue-50 p-4">
<div className="mb-2 flex items-center justify-between">
<span className="text-sm font-semibold text-gray-700">Active QR codes</span>
<span className="text-2xl font-bold text-blue-600">3 / 50 / 500</span>
</div>
<div className="text-xs text-gray-600">Plan-based dynamic QR capacity</div>
</div>
<div className="grid grid-cols-2 gap-3">
<div className="rounded-lg border border-green-200 bg-green-50 p-3">
<div className="mb-1 text-xs text-gray-600">Total scans</div>
<div className="text-xl font-bold text-green-600">Dashboard metric</div>
</div>
<div className="rounded-lg border border-purple-200 bg-purple-50 p-3">
<div className="mb-1 text-xs text-gray-600">Unique scans</div>
<div className="text-xl font-bold text-purple-600">Dashboard metric</div>
</div>
</div>
<div className="rounded-lg border border-gray-200 bg-gray-50 p-3">
<div className="mb-2 text-xs text-gray-600">Available actions</div>
<div className="flex flex-wrap gap-2 text-xs text-gray-700">
<span className="rounded-full bg-white px-3 py-1">View details</span>
<span className="rounded-full bg-white px-3 py-1">Download PNG</span>
<span className="rounded-full bg-white px-3 py-1">Download SVG</span>
<span className="rounded-full bg-white px-3 py-1">Edit dynamic QR</span>
<span className="rounded-full bg-white px-3 py-1">Delete</span>
</div>
</div>
</div>
</Card>
</div>
</div>
</div>
</section>
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<AnswerFirstBlock
whatIsIt="QR Master management is a dashboard workflow for reviewing QR codes, editing dynamic destinations, downloading files, and checking scan activity from one place. It is most useful when your QR program is active enough that single-file handling becomes messy."
whenToUse={[
'You need one place to review active QR codes and their scan totals',
'You want to edit dynamic QR destinations after print without replacing the QR image',
'You need to keep static and dynamic QR workflows organized around current plan limits',
]}
comparison={{
leftTitle: 'Manual handling',
rightTitle: 'Dashboard management',
items: [
{ label: 'See active QR codes in one place', value: true, text: 'Scattered across files or exports' },
{ label: 'Edit dynamic destinations later', value: true, text: 'Not possible outside dynamic QR management' },
{ label: 'Review scan totals and unique scans', value: true, text: 'No unified dashboard view' },
],
}}
howTo={{
steps: [
'Create or save QR codes into your QR Master account',
'Open the dashboard to review active codes, scans, and available actions',
'Edit dynamic destinations or download the QR files you need for the next workflow',
],
}}
/>
</div>
<div className="container mx-auto max-w-5xl px-4 pb-8 sm:px-6 lg:px-8">
<FAQSection items={faqItems} title="QR management questions" />
</div>
<section className="bg-gray-50 py-20">
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="mb-16 text-center">
<h2 className="mb-4 text-4xl font-bold text-gray-900">What the current dashboard supports</h2>
<p className="mx-auto max-w-3xl text-xl text-gray-600">
These capabilities are tied to the present product surface rather than future or inferred roadmap features.
</p>
</div>
<div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
{verifiedCapabilities.map((feature) => (
<Card key={feature.title} className="p-6 transition-shadow hover:shadow-lg">
<h3 className="mb-2 text-xl font-semibold text-gray-900">{feature.title}</h3>
<p className="text-gray-600">{feature.description}</p>
</Card>
))}
</div>
</div>
</section>
<section className="py-20">
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="mb-16 text-center">
<h2 className="mb-4 text-4xl font-bold text-gray-900">Where QR management is most useful</h2>
<p className="mx-auto max-w-3xl text-xl text-gray-600">
Use the dashboard when your QR workflows need ongoing edits, downloads, and visibility instead of one-off creation.
</p>
</div>
<div className="grid gap-8 md:grid-cols-2">
{operationalUseCases.map((useCase) => (
<Card key={useCase.title} className="p-8">
<h3 className="mb-3 text-2xl font-bold text-gray-900">{useCase.title}</h3>
<p className="mb-6 text-gray-600">{useCase.description}</p>
<ul className="space-y-2">
{useCase.points.map((point) => (
<li key={point} className="flex items-center gap-2">
<svg className="h-5 w-5 flex-shrink-0 text-green-500" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clipRule="evenodd"
/>
</svg>
<span className="text-gray-700">{point}</span>
</li>
))}
</ul>
</Card>
))}
</div>
</div>
</section>
<section className="bg-gradient-to-r from-green-600 to-blue-600 py-20 text-white">
<div className="container mx-auto max-w-5xl px-4 text-center sm:px-6 lg:px-8">
<h2 className="mb-6 text-4xl font-bold">Start managing your QR codes with one account</h2>
<p className="mb-8 text-xl text-green-100">
Keep dynamic updates, downloads, and scan reporting in one dashboard instead of spreading the workflow across files and ad hoc links.
</p>
<div className="flex flex-col justify-center gap-4 sm:flex-row">
<Link href="/signup">
<Button
size="lg"
variant="secondary"
className="w-full bg-white px-8 py-4 text-lg text-green-600 hover:bg-gray-100 sm:w-auto"
>
Get Started Free
</Button>
</Link>
<Link href="/pricing">
<Button
size="lg"
variant="outline"
className="w-full border-white px-8 py-4 text-lg text-white hover:bg-white/10 sm:w-auto"
>
View Pricing
</Button>
</Link>
</div>
</div>
</section>
</div>
</>
);
}
import React from 'react';
import type { Metadata } from 'next';
import Link from 'next/link';
import { Button } from '@/components/ui/Button';
import { Card } from '@/components/ui/Card';
import SeoJsonLd from '@/components/SeoJsonLd';
import Breadcrumbs, { BreadcrumbItem } from '@/components/Breadcrumbs';
import { breadcrumbSchema, faqPageSchema } from '@/lib/schema';
import { AnswerFirstBlock } from '@/components/marketing/AnswerFirstBlock';
import { FAQSection } from '@/components/aeo/FAQSection';
export const metadata: Metadata = {
title: {
absolute: 'Manage QR Codes - Dashboard, Edits, and Analytics',
},
description:
'Manage QR codes in one dashboard. Review active codes, edit dynamic destinations, see scan totals and unique scans, and work within current Free, Pro, or Business limits.',
keywords: [
'manage qr codes',
'qr code dashboard',
'edit dynamic qr codes',
'qr code analytics dashboard',
'qr code management',
],
alternates: {
canonical: 'https://www.qrmaster.net/manage-qr-codes',
languages: {
'x-default': 'https://www.qrmaster.net/manage-qr-codes',
en: 'https://www.qrmaster.net/manage-qr-codes',
},
},
openGraph: {
title: 'Manage QR Codes - Dashboard, Edits, and Analytics',
description:
'Use one dashboard to review QR codes, edit dynamic destinations, and check scan totals and unique scans.',
url: 'https://www.qrmaster.net/manage-qr-codes',
type: 'website',
images: [
{
url: '/images/og/og-manage-qr-codes.png',
width: 1200,
height: 630,
},
],
},
twitter: {
title: 'Manage QR Codes - Dashboard, Edits, and Analytics',
description:
'Use one dashboard to review QR codes, edit dynamic destinations, and check scan totals and unique scans.',
},
};
const verifiedCapabilities = [
{
title: 'Central dashboard',
description:
'The dashboard lists your QR codes in one place instead of forcing you to manage separate files or links manually.',
},
{
title: 'Dynamic destination edits',
description:
'Dynamic QR codes can be edited after print. Static QR codes remain fixed.',
},
{
title: 'Scan reporting',
description:
'The current dashboard reports total scans, active codes, and unique scans, with analytics pages adding more context.',
},
{
title: 'Plan-based limits',
description:
'Free includes 3 dynamic QR codes, Pro includes 50, and Business includes 500. Static QR codes remain unlimited.',
},
{
title: 'Tags and status',
description:
'QR code records support tags and active status, which helps keep batches and single-code workflows easier to review.',
},
{
title: 'Download and delete actions',
description:
'Each QR code card supports view, download, edit for dynamic QR codes, and delete actions from the dashboard surface.',
},
];
const operationalUseCases = [
{
title: 'Marketing campaigns',
description:
'Review active dynamic QR codes, compare scan totals, and update destinations when campaigns or landing pages change.',
points: ['One list of active codes', 'Scan totals and unique scans', 'Edit dynamic destinations'],
},
{
title: 'Restaurants and hospitality',
description:
'Keep menu or table-card QR codes current from the dashboard instead of reprinting every time the destination changes.',
points: ['Update menu destinations', 'Monitor scan activity', 'Keep print assets in use longer'],
},
{
title: 'Product and packaging workflows',
description:
'Track which QR codes are active, save batches to the dashboard, and separate static bulk output from dynamic campaign codes.',
points: ['Save generated QR codes', 'Review active status', 'Manage static and dynamic codes separately'],
},
{
title: 'Small team or solo workflows',
description:
'Use one account to keep QR code creation, edits, downloads, and analytics in one operational place.',
points: ['Single dashboard view', 'No spreadsheet-only workflow', 'Clear plan limits'],
},
];
const faqItems = [
{
question: 'What does it mean to manage QR codes?',
answer:
'In QR Master, managing QR codes means using one dashboard to review your QR codes, edit dynamic destinations, download files, and check scan activity instead of tracking everything manually.',
},
{
question: 'Can I edit a QR code after printing it?',
answer:
'Yes, if it is a dynamic QR code. Static QR codes stay fixed after creation.',
},
{
question: 'How many dynamic QR codes can I manage?',
answer:
'Free includes 3 dynamic QR codes, Pro includes 50, and Business includes 500. Static QR codes are unlimited.',
},
{
question: 'What analytics are visible today?',
answer:
'The current dashboard shows total scans, active QR codes, and unique scans. Additional analytics views add more scan context such as time, device, and location.',
},
{
question: 'Does the current product include team roles or API-based QR management?',
answer:
'This page only reflects the verified current surface: dashboard management, dynamic edits, analytics, downloads, tags, and plan limits. It does not claim team roles or public API-based QR management as current verified capabilities.',
},
];
const softwareSchema = {
'@context': 'https://schema.org',
'@type': 'SoftwareApplication',
'@id': 'https://www.qrmaster.net/manage-qr-codes#software',
name: 'QR Master - QR Code Management Dashboard',
applicationCategory: 'BusinessApplication',
offers: {
'@type': 'AggregateOffer',
lowPrice: '0',
highPrice: '29',
priceCurrency: 'EUR',
},
featureList: [
'Central QR code dashboard',
'Edit dynamic QR code destinations',
'Review total and unique scan counts',
'Download QR codes as PNG or SVG',
'Tag QR code records and review active status',
'Manage current plan limits for dynamic QR codes',
],
};
const breadcrumbItems: BreadcrumbItem[] = [
{ name: 'Home', url: '/' },
{ name: 'Manage QR Codes', url: '/manage-qr-codes' },
];
export default function ManageQRCodesPage() {
return (
<>
<SeoJsonLd
data={[
softwareSchema,
breadcrumbSchema(breadcrumbItems),
faqPageSchema(faqItems),
]}
/>
<div className="min-h-screen bg-white">
<section className="relative overflow-hidden bg-gradient-to-br from-green-50 via-white to-blue-50 py-20">
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<Breadcrumbs items={breadcrumbItems} />
<div className="mt-8 grid items-center gap-12 lg:grid-cols-2">
<div className="space-y-8">
<div className="inline-flex items-center rounded-full bg-green-100 px-4 py-2 text-sm font-semibold text-green-800">
Dashboard-first QR management
</div>
<div className="space-y-5">
<h1 className="text-5xl font-bold leading-tight text-gray-900 lg:text-6xl">
Manage QR Codes from one dashboard
</h1>
<p className="text-xl leading-relaxed text-gray-600">
Review active QR codes, edit dynamic destinations, download files, and
monitor scan totals from one place instead of managing printed QR workflows manually.
</p>
</div>
<div className="space-y-3">
{[
'See QR codes in one dashboard',
'Edit dynamic destinations after print',
'Review total scans, active codes, and unique scans',
'Work within the current Free, Pro, and Business dynamic QR limits',
].map((feature) => (
<div key={feature} className="flex items-center gap-3">
<div className="flex h-5 w-5 items-center justify-center rounded-full bg-green-500">
<svg className="h-3 w-3 text-white" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clipRule="evenodd"
/>
</svg>
</div>
<span className="text-gray-700">{feature}</span>
</div>
))}
</div>
<div className="flex flex-col gap-4 sm:flex-row">
<Link href="/signup">
<Button size="lg" className="w-full px-8 py-4 text-lg sm:w-auto">
Get Started Free
</Button>
</Link>
<Link href="/pricing">
<Button variant="outline" size="lg" className="w-full px-8 py-4 text-lg sm:w-auto">
View Pricing
</Button>
</Link>
</div>
</div>
<div className="relative">
<Card className="p-6 shadow-2xl">
<h3 className="mb-4 text-lg font-semibold">Dashboard snapshot</h3>
<div className="space-y-3">
<div className="rounded-lg border border-blue-200 bg-blue-50 p-4">
<div className="mb-2 flex items-center justify-between">
<span className="text-sm font-semibold text-gray-700">Active QR codes</span>
<span className="text-2xl font-bold text-blue-600">3 / 50 / 500</span>
</div>
<div className="text-xs text-gray-600">Plan-based dynamic QR capacity</div>
</div>
<div className="grid grid-cols-2 gap-3">
<div className="rounded-lg border border-green-200 bg-green-50 p-3">
<div className="mb-1 text-xs text-gray-600">Total scans</div>
<div className="text-xl font-bold text-green-600">Dashboard metric</div>
</div>
<div className="rounded-lg border border-purple-200 bg-purple-50 p-3">
<div className="mb-1 text-xs text-gray-600">Unique scans</div>
<div className="text-xl font-bold text-purple-600">Dashboard metric</div>
</div>
</div>
<div className="rounded-lg border border-gray-200 bg-gray-50 p-3">
<div className="mb-2 text-xs text-gray-600">Available actions</div>
<div className="flex flex-wrap gap-2 text-xs text-gray-700">
<span className="rounded-full bg-white px-3 py-1">View details</span>
<span className="rounded-full bg-white px-3 py-1">Download PNG</span>
<span className="rounded-full bg-white px-3 py-1">Download SVG</span>
<span className="rounded-full bg-white px-3 py-1">Edit dynamic QR</span>
<span className="rounded-full bg-white px-3 py-1">Delete</span>
</div>
</div>
</div>
</Card>
</div>
</div>
</div>
</section>
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<AnswerFirstBlock
whatIsIt="QR Master management is a dashboard workflow for reviewing QR codes, editing dynamic destinations, downloading files, and checking scan activity from one place. It is most useful when your QR program is active enough that single-file handling becomes messy."
whenToUse={[
'You need one place to review active QR codes and their scan totals',
'You want to edit dynamic QR destinations after print without replacing the QR image',
'You need to keep static and dynamic QR workflows organized around current plan limits',
]}
comparison={{
leftTitle: 'Manual handling',
rightTitle: 'Dashboard management',
items: [
{ label: 'See active QR codes in one place', value: true, text: 'Scattered across files or exports' },
{ label: 'Edit dynamic destinations later', value: true, text: 'Not possible outside dynamic QR management' },
{ label: 'Review scan totals and unique scans', value: true, text: 'No unified dashboard view' },
],
}}
howTo={{
steps: [
'Create or save QR codes into your QR Master account',
'Open the dashboard to review active codes, scans, and available actions',
'Edit dynamic destinations or download the QR files you need for the next workflow',
],
}}
/>
</div>
<div className="container mx-auto max-w-5xl px-4 pb-8 sm:px-6 lg:px-8">
<FAQSection items={faqItems} title="QR management questions" />
</div>
<section className="bg-gray-50 py-20">
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="mb-16 text-center">
<h2 className="mb-4 text-4xl font-bold text-gray-900">What the current dashboard supports</h2>
<p className="mx-auto max-w-3xl text-xl text-gray-600">
These capabilities are tied to the present product surface rather than future or inferred roadmap features.
</p>
</div>
<div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
{verifiedCapabilities.map((feature) => (
<Card key={feature.title} className="p-6 transition-shadow hover:shadow-lg">
<h3 className="mb-2 text-xl font-semibold text-gray-900">{feature.title}</h3>
<p className="text-gray-600">{feature.description}</p>
</Card>
))}
</div>
</div>
</section>
<section className="py-20">
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="mb-16 text-center">
<h2 className="mb-4 text-4xl font-bold text-gray-900">Where QR management is most useful</h2>
<p className="mx-auto max-w-3xl text-xl text-gray-600">
Use the dashboard when your QR workflows need ongoing edits, downloads, and visibility instead of one-off creation.
</p>
</div>
<div className="grid gap-8 md:grid-cols-2">
{operationalUseCases.map((useCase) => (
<Card key={useCase.title} className="p-8">
<h3 className="mb-3 text-2xl font-bold text-gray-900">{useCase.title}</h3>
<p className="mb-6 text-gray-600">{useCase.description}</p>
<ul className="space-y-2">
{useCase.points.map((point) => (
<li key={point} className="flex items-center gap-2">
<svg className="h-5 w-5 flex-shrink-0 text-green-500" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clipRule="evenodd"
/>
</svg>
<span className="text-gray-700">{point}</span>
</li>
))}
</ul>
</Card>
))}
</div>
</div>
</section>
<section className="bg-gradient-to-r from-green-600 to-blue-600 py-20 text-white">
<div className="container mx-auto max-w-5xl px-4 text-center sm:px-6 lg:px-8">
<h2 className="mb-6 text-4xl font-bold">Start managing your QR codes with one account</h2>
<p className="mb-8 text-xl text-green-100">
Keep dynamic updates, downloads, and scan reporting in one dashboard instead of spreading the workflow across files and ad hoc links.
</p>
<div className="flex flex-col justify-center gap-4 sm:flex-row">
<Link href="/signup">
<Button
size="lg"
variant="secondary"
className="w-full bg-white px-8 py-4 text-lg text-green-600 hover:bg-gray-100 sm:w-auto"
>
Get Started Free
</Button>
</Link>
<Link href="/pricing">
<Button
size="lg"
variant="outline"
className="w-full border-white px-8 py-4 text-lg text-white hover:bg-white/10 sm:w-auto"
>
View Pricing
</Button>
</Link>
</div>
</div>
</section>
</div>
</>
);
}

View File

@@ -1,118 +1,118 @@
import React from 'react';
import type { Metadata } from 'next';
import PricingClient from './PricingClient';
import SeoJsonLd from '@/components/SeoJsonLd';
import { AnswerFirstBlock } from '@/components/marketing/AnswerFirstBlock';
import { FAQSection } from '@/components/aeo/FAQSection';
import { breadcrumbSchema, faqPageSchema } from '@/lib/schema';
export const metadata: Metadata = {
title: {
absolute: 'Pricing Plans | QR Master',
},
description:
'Compare QR Master pricing plans. Free includes 3 active dynamic QR codes, Pro includes 50, and Business includes 500 plus bulk QR creation.',
alternates: {
canonical: 'https://www.qrmaster.net/pricing',
},
robots: {
index: true,
follow: true,
},
openGraph: {
title: 'Pricing Plans | QR Master',
description:
'Compare QR Master pricing plans. Free includes 3 active dynamic QR codes, Pro includes 50, and Business includes 500 plus bulk QR creation.',
url: 'https://www.qrmaster.net/pricing',
type: 'website',
images: [
{
url: 'https://www.qrmaster.net/og-image.png',
width: 1200,
height: 630,
alt: 'QR Master Pricing Plans',
},
],
},
};
const faqItems = [
{
question: 'How many dynamic QR codes are included in each plan?',
answer:
'Free includes 3 active dynamic QR codes. Pro includes 50 dynamic QR codes. Business includes 500 dynamic QR codes.',
},
{
question: 'Do all plans include static QR codes?',
answer:
'Yes. All plans include unlimited static QR codes.',
},
{
question: 'Which plan includes bulk QR creation?',
answer:
'Bulk QR creation is included in the Business plan.',
},
{
question: 'Which plans include analytics and branding?',
answer:
'The Free plan includes basic scan tracking. Pro adds advanced analytics and custom branding. Business includes everything from Pro plus bulk QR creation and priority email support.',
},
];
const breadcrumbItems = [
{ name: 'Home', url: '/' },
{ name: 'Pricing', url: '/pricing' },
];
export default function PricingPage() {
return (
<>
<SeoJsonLd data={[breadcrumbSchema(breadcrumbItems), faqPageSchema(faqItems)]} />
<div className="bg-white">
<div className="container mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8">
<AnswerFirstBlock
whatIsIt="QR Master pricing is organized around how many active dynamic QR codes you need and whether you need advanced analytics, branding, or bulk creation. Free includes 3 active dynamic QR codes, Pro includes 50, and Business includes 500 plus bulk QR creation."
whenToUse={[
'Choose Free when you need a small number of active dynamic QR codes and unlimited static QR codes',
'Choose Pro when you need more active dynamic QR codes plus advanced analytics and custom branding',
'Choose Business when you need 500 active dynamic QR codes and the bulk QR creation workflow',
]}
comparison={{
leftTitle: 'Lower plans',
rightTitle: 'Higher plan adds',
items: [
{ label: 'Dynamic QR capacity', value: true, text: '3 or 50 active codes' },
{ label: 'Bulk QR creation', value: true, text: 'Not included before Business' },
{ label: 'Advanced analytics and branding', value: true, text: 'Basic or Pro-level only' },
],
}}
howTo={{
steps: [
'Estimate how many active dynamic QR codes you need at one time',
'Decide whether you also need advanced analytics, branding, or bulk creation',
'Choose the plan that matches the current workflow instead of paying for unused capacity',
],
}}
/>
</div>
<div className="container mx-auto max-w-5xl px-4 pb-4 sm:px-6 lg:px-8">
<FAQSection items={faqItems} title="Pricing questions" />
</div>
<div className="sr-only">
<h2>Compare our plans</h2>
<p>
Free includes 3 active dynamic QR codes and unlimited static QR codes. Pro
includes 50 dynamic QR codes, advanced analytics, and custom branding.
Business includes 500 dynamic QR codes, everything from Pro, bulk QR creation
up to 1,000, and priority email support.
</p>
</div>
<PricingClient />
</div>
</>
);
}
import React from 'react';
import type { Metadata } from 'next';
import PricingClient from './PricingClient';
import SeoJsonLd from '@/components/SeoJsonLd';
import { AnswerFirstBlock } from '@/components/marketing/AnswerFirstBlock';
import { FAQSection } from '@/components/aeo/FAQSection';
import { breadcrumbSchema, faqPageSchema } from '@/lib/schema';
export const metadata: Metadata = {
title: {
absolute: 'Pricing Plans | QR Master',
},
description:
'Compare QR Master pricing plans. Free includes 3 active dynamic QR codes, Pro includes 50, and Business includes 500 plus bulk QR creation.',
alternates: {
canonical: 'https://www.qrmaster.net/pricing',
},
robots: {
index: true,
follow: true,
},
openGraph: {
title: 'Pricing Plans | QR Master',
description:
'Compare QR Master pricing plans. Free includes 3 active dynamic QR codes, Pro includes 50, and Business includes 500 plus bulk QR creation.',
url: 'https://www.qrmaster.net/pricing',
type: 'website',
images: [
{
url: 'https://www.qrmaster.net/og-image.png',
width: 1200,
height: 630,
alt: 'QR Master Pricing Plans',
},
],
},
};
const faqItems = [
{
question: 'How many dynamic QR codes are included in each plan?',
answer:
'Free includes 3 active dynamic QR codes. Pro includes 50 dynamic QR codes. Business includes 500 dynamic QR codes.',
},
{
question: 'Do all plans include static QR codes?',
answer:
'Yes. All plans include unlimited static QR codes.',
},
{
question: 'Which plan includes bulk QR creation?',
answer:
'Bulk QR creation is included in the Business plan.',
},
{
question: 'Which plans include analytics and branding?',
answer:
'The Free plan includes basic scan tracking. Pro adds advanced analytics and custom branding. Business includes everything from Pro plus bulk QR creation and priority email support.',
},
];
const breadcrumbItems = [
{ name: 'Home', url: '/' },
{ name: 'Pricing', url: '/pricing' },
];
export default function PricingPage() {
return (
<>
<SeoJsonLd data={[breadcrumbSchema(breadcrumbItems), faqPageSchema(faqItems)]} />
<div className="bg-white">
<div className="container mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8">
<AnswerFirstBlock
whatIsIt="QR Master pricing is organized around how many active dynamic QR codes you need and whether you need advanced analytics, branding, or bulk creation. Free includes 3 active dynamic QR codes, Pro includes 50, and Business includes 500 plus bulk QR creation."
whenToUse={[
'Choose Free when you need a small number of active dynamic QR codes and unlimited static QR codes',
'Choose Pro when you need more active dynamic QR codes plus advanced analytics and custom branding',
'Choose Business when you need 500 active dynamic QR codes and the bulk QR creation workflow',
]}
comparison={{
leftTitle: 'Lower plans',
rightTitle: 'Higher plan adds',
items: [
{ label: 'Dynamic QR capacity', value: true, text: '3 or 50 active codes' },
{ label: 'Bulk QR creation', value: true, text: 'Not included before Business' },
{ label: 'Advanced analytics and branding', value: true, text: 'Basic or Pro-level only' },
],
}}
howTo={{
steps: [
'Estimate how many active dynamic QR codes you need at one time',
'Decide whether you also need advanced analytics, branding, or bulk creation',
'Choose the plan that matches the current workflow instead of paying for unused capacity',
],
}}
/>
</div>
<div className="container mx-auto max-w-5xl px-4 pb-4 sm:px-6 lg:px-8">
<FAQSection items={faqItems} title="Pricing questions" />
</div>
<div className="sr-only">
<h2>Compare our plans</h2>
<p>
Free includes 3 active dynamic QR codes and unlimited static QR codes. Pro
includes 50 dynamic QR codes, advanced analytics, and custom branding.
Business includes 500 dynamic QR codes, everything from Pro, bulk QR creation
up to 1,000, and priority email support.
</p>
</div>
<PricingClient />
</div>
</>
);
}

View File

@@ -1,143 +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]}
/>
);
}
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

@@ -1,112 +1,112 @@
import type { Metadata } from "next";
import {
buildUseCaseMetadata,
UseCasePageTemplate,
} from "@/components/marketing/UseCasePageTemplate";
export const metadata: Metadata = buildUseCaseMetadata({
title: "QR Codes for Marketing Campaigns",
description:
"Plan QR codes for marketing campaigns around placement tracking, changing destinations, and offline-to-online attribution.",
canonicalPath: "/qr-code-for-marketing-campaigns",
});
export default function QRCodeForMarketingCampaignsPage() {
return (
<UseCasePageTemplate
title="QR Codes for Marketing Campaigns"
description="Plan QR codes for marketing campaigns around placement tracking, changing destinations, and offline-to-online attribution."
eyebrow="Campaign Workflows"
intro="Marketing campaign QR codes work best when the code on the printed asset stays stable while the destination and attribution model can evolve with the campaign."
pageType="commercial"
cluster="marketing-campaigns"
useCase="marketing-campaigns"
breadcrumbs={[
{ name: "Home", url: "/" },
{
name: "QR Codes for Marketing Campaigns",
url: "/qr-code-for-marketing-campaigns",
},
]}
answer="A campaign QR code should do more than open a page. It should help you compare placements, update the destination when the offer changes, and route offline traffic into a measurable funnel."
whenToUse={[
"You run flyers, posters, packaging inserts, or event signage with campaign-specific CTA copy.",
"You want to compare placements or creatives instead of treating every scan as generic traffic.",
"Your destination may change during the life of the printed campaign.",
]}
comparisonItems={[
{ label: "Offer updates", text: "New print required", value: true },
{ label: "Placement attribution", text: "Often manual", value: true },
{ label: "Creative testing", text: "Hard to manage", value: true },
]}
howToSteps={[
"Create campaign QR flows around one clear action and one named placement context.",
"Use dynamic destinations or tagged URLs so the print stays usable when the offer changes.",
"Measure scans with a clean CTA path into signup, lead capture, or campaign landing pages.",
]}
primaryCta={{
href: "/dynamic-qr-code-generator",
label: "Create a trackable campaign QR",
}}
secondaryCta={{
href: "/use-cases",
label: "Browse use-case workflows",
}}
workflowTitle="What strong campaign QR workflows look like"
workflowIntro="Campaign QR strategy becomes more useful when creative, placement, and destination are treated as a system rather than a single link printed everywhere."
workflowCards={[
{
title: "Placement-aware routing",
description: "Keep banner, flyer, packaging, and in-store placements comparable by using distinct destinations or campaign tags.",
},
{
title: "Post-print flexibility",
description: "Adjust the landing page, offer, or CTA destination after print when the campaign learns something or needs a fast update.",
},
{
title: "Measurement-ready handoff",
description: "Push campaign scans toward signup, booking, or lead-gen paths so the QR is tied to a business outcome instead of a vanity click.",
},
]}
checklistTitle="Campaign QR checklist"
checklist={[
"Match each QR code to one campaign purpose and one primary CTA.",
"Differentiate placements with clean naming or URL tagging before the assets go to print.",
"Use a destination you can update when the promotion, offer, or landing page changes.",
"Link the campaign flow back to a measured CTA path instead of stopping at raw scan counts.",
]}
supportLinks={[
{
href: "/qr-code-tracking",
title: "QR Code Tracking",
description: "Use when the real priority is measuring placement and scanner context.",
},
{
href: "/custom-qr-code-generator",
title: "Custom QR Code Generator",
description: "Useful when brand fit and print creative need more control.",
},
{
href: "/blog/utm-parameter-qr-codes",
title: "UTM Parameters with QR Codes",
description: "Support article for placement naming and campaign attribution strategy.",
},
]}
faq={[
{
question: "Why use QR codes in marketing campaigns?",
answer: "Campaign QR codes help move offline audiences into a measurable online path. They are most useful when the destination and tracking setup are planned before the assets go live.",
},
{
question: "Should campaign QR codes be dynamic?",
answer: "Yes, when the destination, offer, or campaign landing page may change after print. That avoids replacing materials just because the target page changes.",
},
{
question: "How do I track different QR placements in one campaign?",
answer: "Use distinct destinations or tagged URLs for each placement so flyers, posters, booth signs, and packaging inserts can be compared cleanly.",
},
]}
/>
);
}
import type { Metadata } from "next";
import {
buildUseCaseMetadata,
UseCasePageTemplate,
} from "@/components/marketing/UseCasePageTemplate";
export const metadata: Metadata = buildUseCaseMetadata({
title: "QR Codes for Marketing Campaigns",
description:
"Plan QR codes for marketing campaigns around placement tracking, changing destinations, and offline-to-online attribution.",
canonicalPath: "/qr-code-for-marketing-campaigns",
});
export default function QRCodeForMarketingCampaignsPage() {
return (
<UseCasePageTemplate
title="QR Codes for Marketing Campaigns"
description="Plan QR codes for marketing campaigns around placement tracking, changing destinations, and offline-to-online attribution."
eyebrow="Campaign Workflows"
intro="Marketing campaign QR codes work best when the code on the printed asset stays stable while the destination and attribution model can evolve with the campaign."
pageType="commercial"
cluster="marketing-campaigns"
useCase="marketing-campaigns"
breadcrumbs={[
{ name: "Home", url: "/" },
{
name: "QR Codes for Marketing Campaigns",
url: "/qr-code-for-marketing-campaigns",
},
]}
answer="A campaign QR code should do more than open a page. It should help you compare placements, update the destination when the offer changes, and route offline traffic into a measurable funnel."
whenToUse={[
"You run flyers, posters, packaging inserts, or event signage with campaign-specific CTA copy.",
"You want to compare placements or creatives instead of treating every scan as generic traffic.",
"Your destination may change during the life of the printed campaign.",
]}
comparisonItems={[
{ label: "Offer updates", text: "New print required", value: true },
{ label: "Placement attribution", text: "Often manual", value: true },
{ label: "Creative testing", text: "Hard to manage", value: true },
]}
howToSteps={[
"Create campaign QR flows around one clear action and one named placement context.",
"Use dynamic destinations or tagged URLs so the print stays usable when the offer changes.",
"Measure scans with a clean CTA path into signup, lead capture, or campaign landing pages.",
]}
primaryCta={{
href: "/dynamic-qr-code-generator",
label: "Create a trackable campaign QR",
}}
secondaryCta={{
href: "/use-cases",
label: "Browse use-case workflows",
}}
workflowTitle="What strong campaign QR workflows look like"
workflowIntro="Campaign QR strategy becomes more useful when creative, placement, and destination are treated as a system rather than a single link printed everywhere."
workflowCards={[
{
title: "Placement-aware routing",
description: "Keep banner, flyer, packaging, and in-store placements comparable by using distinct destinations or campaign tags.",
},
{
title: "Post-print flexibility",
description: "Adjust the landing page, offer, or CTA destination after print when the campaign learns something or needs a fast update.",
},
{
title: "Measurement-ready handoff",
description: "Push campaign scans toward signup, booking, or lead-gen paths so the QR is tied to a business outcome instead of a vanity click.",
},
]}
checklistTitle="Campaign QR checklist"
checklist={[
"Match each QR code to one campaign purpose and one primary CTA.",
"Differentiate placements with clean naming or URL tagging before the assets go to print.",
"Use a destination you can update when the promotion, offer, or landing page changes.",
"Link the campaign flow back to a measured CTA path instead of stopping at raw scan counts.",
]}
supportLinks={[
{
href: "/qr-code-tracking",
title: "QR Code Tracking",
description: "Use when the real priority is measuring placement and scanner context.",
},
{
href: "/custom-qr-code-generator",
title: "Custom QR Code Generator",
description: "Useful when brand fit and print creative need more control.",
},
{
href: "/blog/utm-parameter-qr-codes",
title: "UTM Parameters with QR Codes",
description: "Support article for placement naming and campaign attribution strategy.",
},
]}
faq={[
{
question: "Why use QR codes in marketing campaigns?",
answer: "Campaign QR codes help move offline audiences into a measurable online path. They are most useful when the destination and tracking setup are planned before the assets go live.",
},
{
question: "Should campaign QR codes be dynamic?",
answer: "Yes, when the destination, offer, or campaign landing page may change after print. That avoids replacing materials just because the target page changes.",
},
{
question: "How do I track different QR placements in one campaign?",
answer: "Use distinct destinations or tagged URLs for each placement so flyers, posters, booth signs, and packaging inserts can be compared cleanly.",
},
]}
/>
);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,143 +1,143 @@
import React from 'react';
import Link from 'next/link';
import { Metadata } from 'next';
import { Button } from '@/components/ui/Button';
import SeoJsonLd from '@/components/SeoJsonLd';
import { organizationSchema, reviewSchema, aggregateRatingSchema } from '@/lib/schema';
import { testimonials, getAggregateRating } from '@/lib/testimonial-data';
import { Testimonials } from '@/components/marketing/Testimonials';
import { Star } from 'lucide-react';
function truncateAtWord(text: string, maxLength: number): string {
if (text.length <= maxLength) return text;
const truncated = text.slice(0, maxLength);
const lastSpace = truncated.lastIndexOf(' ');
return lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated;
}
export async function generateMetadata(): Promise<Metadata> {
const title = truncateAtWord('Customer Testimonials | QR Master Reviews', 60);
const description = truncateAtWord(
'Read what our customers say about QR Master. Real reviews from businesses using dynamic QR codes for restaurants, pottery, retail, events, and more.',
160
);
return {
title,
description,
keywords: ['qr master reviews', 'qr code testimonials', 'customer reviews', 'qr code generator reviews', 'dynamic qr code reviews'],
alternates: {
canonical: 'https://www.qrmaster.net/testimonials',
},
openGraph: {
title,
description,
url: 'https://www.qrmaster.net/testimonials',
type: 'website',
images: [
{
url: 'https://www.qrmaster.net/og-image.png',
width: 1200,
height: 630,
alt: 'QR Master Customer Testimonials',
},
],
},
twitter: {
title,
description,
},
};
}
export default function TestimonialsPage() {
const aggregateRating = getAggregateRating();
const reviewSchemas = testimonials.map(t => reviewSchema(t));
return (
<>
<SeoJsonLd data={[
organizationSchema(),
aggregateRatingSchema(aggregateRating),
...reviewSchemas
]} />
<div className="bg-white">
{/* Hero Section with Aggregate Rating */}
<section className="relative overflow-hidden bg-gradient-to-br from-blue-50 via-white to-purple-50 py-20 sm:py-24">
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-5xl text-center">
<h1 className="text-4xl sm:text-5xl font-bold text-gray-900 leading-tight mb-6">
Customer <span className="text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-purple-600">Testimonials</span>
</h1>
<p className="text-xl text-gray-600 max-w-2xl mx-auto mb-8 leading-relaxed">
Real experiences from businesses using QR Master to create dynamic QR codes
</p>
{/* Aggregate Rating Display */}
<div className="flex flex-col items-center justify-center gap-3 mb-10">
<div className="flex gap-1" aria-label={`${aggregateRating.ratingValue} out of 5 stars`}>
{[...Array(5)].map((_, index) => (
<Star
key={index}
className={`w-8 h-8 ${index < aggregateRating.ratingValue
? 'fill-yellow-400 text-yellow-400'
: 'fill-gray-200 text-gray-200'
}`}
/>
))}
</div>
<p className="text-lg text-gray-700">
<span className="font-bold text-2xl">{aggregateRating.ratingValue}</span> out of 5 stars
</p>
<p className="text-sm text-gray-500">
Based on {aggregateRating.reviewCount} {aggregateRating.reviewCount === 1 ? 'review' : 'reviews'}
</p>
</div>
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
<Link href="/signup">
<Button size="lg" className="text-lg px-8 py-6 shadow-lg shadow-blue-500/25">
Get Started Free
</Button>
</Link>
</div>
</div>
</section>
{/* Testimonials Grid */}
<Testimonials
testimonials={testimonials}
showAll={true}
title="What Our Customers Are Saying"
subtitle="Discover how businesses use QR Master for their unique needs"
/>
{/* CTA Section */}
<section className="py-20 bg-gradient-to-br from-blue-50 via-white to-purple-50">
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-4xl text-center">
<h2 className="text-3xl sm:text-4xl font-bold text-gray-900 mb-6">
Ready to create your own QR codes?
</h2>
<p className="text-xl text-gray-600 mb-10 max-w-2xl mx-auto">
Join businesses using QR Master to create dynamic, trackable QR codes for their products, menus, events, and campaigns.
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
<Link href="/signup">
<Button size="lg" className="text-lg px-8 py-6">
Start Free Today
</Button>
</Link>
<Link href="/pricing">
<Button variant="outline" size="lg" className="text-lg px-8 py-6">
View Pricing
</Button>
</Link>
</div>
</div>
</section>
</div>
</>
);
}
import React from 'react';
import Link from 'next/link';
import { Metadata } from 'next';
import { Button } from '@/components/ui/Button';
import SeoJsonLd from '@/components/SeoJsonLd';
import { organizationSchema, reviewSchema, aggregateRatingSchema } from '@/lib/schema';
import { testimonials, getAggregateRating } from '@/lib/testimonial-data';
import { Testimonials } from '@/components/marketing/Testimonials';
import { Star } from 'lucide-react';
function truncateAtWord(text: string, maxLength: number): string {
if (text.length <= maxLength) return text;
const truncated = text.slice(0, maxLength);
const lastSpace = truncated.lastIndexOf(' ');
return lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated;
}
export async function generateMetadata(): Promise<Metadata> {
const title = truncateAtWord('Customer Testimonials | QR Master Reviews', 60);
const description = truncateAtWord(
'Read what our customers say about QR Master. Real reviews from businesses using dynamic QR codes for restaurants, pottery, retail, events, and more.',
160
);
return {
title,
description,
keywords: ['qr master reviews', 'qr code testimonials', 'customer reviews', 'qr code generator reviews', 'dynamic qr code reviews'],
alternates: {
canonical: 'https://www.qrmaster.net/testimonials',
},
openGraph: {
title,
description,
url: 'https://www.qrmaster.net/testimonials',
type: 'website',
images: [
{
url: 'https://www.qrmaster.net/og-image.png',
width: 1200,
height: 630,
alt: 'QR Master Customer Testimonials',
},
],
},
twitter: {
title,
description,
},
};
}
export default function TestimonialsPage() {
const aggregateRating = getAggregateRating();
const reviewSchemas = testimonials.map(t => reviewSchema(t));
return (
<>
<SeoJsonLd data={[
organizationSchema(),
aggregateRatingSchema(aggregateRating),
...reviewSchemas
]} />
<div className="bg-white">
{/* Hero Section with Aggregate Rating */}
<section className="relative overflow-hidden bg-gradient-to-br from-blue-50 via-white to-purple-50 py-20 sm:py-24">
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-5xl text-center">
<h1 className="text-4xl sm:text-5xl font-bold text-gray-900 leading-tight mb-6">
Customer <span className="text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-purple-600">Testimonials</span>
</h1>
<p className="text-xl text-gray-600 max-w-2xl mx-auto mb-8 leading-relaxed">
Real experiences from businesses using QR Master to create dynamic QR codes
</p>
{/* Aggregate Rating Display */}
<div className="flex flex-col items-center justify-center gap-3 mb-10">
<div className="flex gap-1" aria-label={`${aggregateRating.ratingValue} out of 5 stars`}>
{[...Array(5)].map((_, index) => (
<Star
key={index}
className={`w-8 h-8 ${index < aggregateRating.ratingValue
? 'fill-yellow-400 text-yellow-400'
: 'fill-gray-200 text-gray-200'
}`}
/>
))}
</div>
<p className="text-lg text-gray-700">
<span className="font-bold text-2xl">{aggregateRating.ratingValue}</span> out of 5 stars
</p>
<p className="text-sm text-gray-500">
Based on {aggregateRating.reviewCount} {aggregateRating.reviewCount === 1 ? 'review' : 'reviews'}
</p>
</div>
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
<Link href="/signup">
<Button size="lg" className="text-lg px-8 py-6 shadow-lg shadow-blue-500/25">
Get Started Free
</Button>
</Link>
</div>
</div>
</section>
{/* Testimonials Grid */}
<Testimonials
testimonials={testimonials}
showAll={true}
title="What Our Customers Are Saying"
subtitle="Discover how businesses use QR Master for their unique needs"
/>
{/* CTA Section */}
<section className="py-20 bg-gradient-to-br from-blue-50 via-white to-purple-50">
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-4xl text-center">
<h2 className="text-3xl sm:text-4xl font-bold text-gray-900 mb-6">
Ready to create your own QR codes?
</h2>
<p className="text-xl text-gray-600 mb-10 max-w-2xl mx-auto">
Join businesses using QR Master to create dynamic, trackable QR codes for their products, menus, events, and campaigns.
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
<Link href="/signup">
<Button size="lg" className="text-lg px-8 py-6">
Start Free Today
</Button>
</Link>
<Link href="/pricing">
<Button variant="outline" size="lg" className="text-lg px-8 py-6">
View Pricing
</Button>
</Link>
</div>
</div>
</section>
</div>
</>
);
}

View File

@@ -0,0 +1,179 @@
"use client";
import { useState } from 'react';
type Step = 'use-case' | 'region' | 'result';
type Result = {
format: string;
label: string;
description: string;
example: string;
color: string;
};
const RESULTS: Record<string, Result> = {
'ean13': {
format: 'EAN-13',
label: 'EAN-13',
description: 'The global retail standard. Used on consumer products sold in supermarkets, pharmacies, and online shops worldwide.',
example: '4006381333931 (a common product barcode)',
color: 'blue',
},
'upca': {
format: 'UPC-A',
label: 'UPC-A',
description: 'The North American retail standard. Functionally equivalent to EAN-13 but with 12 digits. Required by US and Canadian retailers.',
example: '012345678905',
color: 'indigo',
},
'code128': {
format: 'Code 128',
label: 'Code 128',
description: 'The most versatile barcode. Supports letters, numbers, and special characters. Used in shipping labels, inventory systems, and internal tracking.',
example: 'SHIP-2026-ABC-001',
color: 'emerald',
},
'code39': {
format: 'Code 39',
label: 'Code 39',
description: 'A legacy alphanumeric format still widely used in automotive, defense, and industrial environments. Simpler than Code 128 but less compact.',
example: 'PART-7734-A',
color: 'orange',
},
'msi': {
format: 'MSI',
label: 'MSI',
description: 'Designed for inventory and shelf labeling in retail warehouses. Numeric-only. Used for bin locations, shelf tags, and stockroom management.',
example: '123456',
color: 'purple',
},
'pharmacode': {
format: 'Pharmacode',
label: 'Pharmacode',
description: 'A pharmaceutical packaging standard used to verify correct product packaging. Encodes a single numeric value (3131071).',
example: '12345',
color: 'red',
},
};
const colorMap: Record<string, string> = {
blue: 'bg-blue-50 border-blue-300 text-blue-900',
indigo: 'bg-indigo-50 border-indigo-300 text-indigo-900',
emerald: 'bg-emerald-50 border-emerald-300 text-emerald-900',
orange: 'bg-orange-50 border-orange-300 text-orange-900',
purple: 'bg-purple-50 border-purple-300 text-purple-900',
red: 'bg-red-50 border-red-300 text-red-900',
};
const badgeMap: Record<string, string> = {
blue: 'bg-blue-100 text-blue-800',
indigo: 'bg-indigo-100 text-indigo-800',
emerald: 'bg-emerald-100 text-emerald-800',
orange: 'bg-orange-100 text-orange-800',
purple: 'bg-purple-100 text-purple-800',
red: 'bg-red-100 text-red-800',
};
export function BarcodeFormatPicker() {
const [step, setStep] = useState<Step>('use-case');
const [useCase, setUseCase] = useState<string>('');
const [result, setResult] = useState<string>('');
const selectUseCase = (value: string) => {
setUseCase(value);
if (value === 'retail') {
setStep('region');
} else {
const map: Record<string, string> = {
logistics: 'code128',
inventory: 'code128',
industrial: 'code39',
warehouse: 'msi',
pharma: 'pharmacode',
};
setResult(map[value] ?? 'code128');
setStep('result');
}
};
const selectRegion = (region: string) => {
setResult(region === 'us' ? 'upca' : 'ean13');
setStep('result');
};
const reset = () => {
setStep('use-case');
setUseCase('');
setResult('');
};
const res = result ? RESULTS[result] : null;
return (
<div className="not-prose my-8 rounded-2xl border border-slate-200 bg-slate-50 p-6">
<h3 className="text-lg font-bold text-slate-900 mb-1">Which barcode format do I need?</h3>
<p className="text-sm text-slate-500 mb-5">Answer two quick questions to find the right format for your use case.</p>
{step === 'use-case' && (
<div>
<p className="text-sm font-semibold text-slate-700 mb-3">What will you use the barcode for?</p>
<div className="grid sm:grid-cols-2 gap-3">
{[
{ value: 'retail', label: 'Retail products', sub: 'Selling in stores or online' },
{ value: 'logistics', label: 'Shipping & logistics', sub: 'Parcel labels, supply chain' },
{ value: 'inventory', label: 'Inventory tracking', sub: 'Internal stock management' },
{ value: 'industrial', label: 'Industrial / automotive', sub: 'Manufacturing, defense' },
{ value: 'warehouse', label: 'Shelf & bin labeling', sub: 'Warehouse locations' },
{ value: 'pharma', label: 'Pharmaceutical packaging', sub: 'Medication packaging control' },
].map((opt) => (
<button
key={opt.value}
onClick={() => selectUseCase(opt.value)}
className="text-left rounded-xl border border-slate-200 bg-white p-4 hover:border-blue-400 hover:bg-blue-50 transition-colors group"
>
<div className="font-semibold text-slate-900 group-hover:text-blue-800 text-sm">{opt.label}</div>
<div className="text-xs text-slate-500 mt-0.5">{opt.sub}</div>
</button>
))}
</div>
</div>
)}
{step === 'region' && (
<div>
<p className="text-sm font-semibold text-slate-700 mb-3">Where will you primarily sell?</p>
<div className="grid sm:grid-cols-2 gap-3">
<button
onClick={() => selectRegion('eu')}
className="text-left rounded-xl border border-slate-200 bg-white p-4 hover:border-blue-400 hover:bg-blue-50 transition-colors group"
>
<div className="font-semibold text-slate-900 group-hover:text-blue-800 text-sm">Europe / International</div>
<div className="text-xs text-slate-500 mt-0.5">EU, UK, Asia, global retail</div>
</button>
<button
onClick={() => selectRegion('us')}
className="text-left rounded-xl border border-slate-200 bg-white p-4 hover:border-blue-400 hover:bg-blue-50 transition-colors group"
>
<div className="font-semibold text-slate-900 group-hover:text-blue-800 text-sm">USA / Canada</div>
<div className="text-xs text-slate-500 mt-0.5">North American retail market</div>
</button>
</div>
<button onClick={reset} className="mt-3 text-xs text-slate-400 hover:text-slate-600 underline"> Start over</button>
</div>
)}
{step === 'result' && res && (
<div className={`rounded-xl border-2 p-5 ${colorMap[res.color]}`}>
<div className="flex items-center gap-3 mb-3">
<span className={`text-xs font-bold px-2.5 py-1 rounded-full ${badgeMap[res.color]}`}>Recommended</span>
<span className="font-bold text-xl">{res.label}</span>
</div>
<p className="text-sm mb-2">{res.description}</p>
<p className="text-xs opacity-70 font-mono">Example: {res.example}</p>
<button onClick={reset} className="mt-4 text-xs underline opacity-60 hover:opacity-90"> Try again</button>
</div>
)}
</div>
);
}

View File

@@ -1,5 +1,7 @@
import { BookOpen, CheckCircle, HelpCircle, Layers, Settings, ShoppingCart, Tag, Activity, Factory } from 'lucide-react';
import { BookOpen, CheckCircle, Layers, Settings, ShoppingCart, Tag, Activity, Factory } from 'lucide-react';
import Link from 'next/link';
import { FAQSection } from '@/components/aeo/FAQSection';
import { BarcodeFormatPicker } from './BarcodeFormatPicker';
export function BarcodeGuide() {
return (
@@ -87,100 +89,59 @@ export function BarcodeGuide() {
Different barcode formats are used for different purposes. Choosing the right one is important for compatibility and scanning accuracy.
</p>
<div className="grid md:grid-cols-2 gap-6 not-prose my-8">
{/* EAN-13 Card */}
<div className="bg-white p-6 rounded-xl border border-slate-200 shadow-sm hover:shadow-md transition-shadow">
<div className="flex items-center gap-3 mb-3">
<Tag className="w-5 h-5 text-blue-500" />
<h4 className="text-lg font-bold text-slate-900 m-0">EAN-13</h4>
</div>
<div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Retail Europe</div>
<div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center">
<img src="/barcode-generator-preview.png" alt="EAN-13 Barcode Sample for International Products" className="h-10 object-contain opacity-75 grayscale" width="200" height="40" />
</div>
<p className="text-sm text-slate-600 m-0">
EAN-13 is widely used in retail, especially in Europe. It is designed for consumer products sold in stores and supermarkets.
</p>
</div>
{/* UPC-A Card */}
<div className="bg-white p-6 rounded-xl border border-slate-200 shadow-sm hover:shadow-md transition-shadow">
<div className="flex items-center gap-3 mb-3">
<ShoppingCart className="w-5 h-5 text-indigo-500" />
<h4 className="text-lg font-bold text-slate-900 m-0">UPC-A</h4>
</div>
<div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Retail USA/Canada</div>
<div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center">
<img src="/barcode-generator-preview.png" alt="UPC-A Barcode Example for Retail Products in USA" className="h-10 object-contain opacity-75 grayscale" width="200" height="40" />
</div>
<p className="text-sm text-slate-600 m-0">
UPC-A is similar to EAN-13 but is mainly used in the United States and Canada for retail products.
</p>
</div>
{/* Code 128 Card */}
<div className="bg-white p-6 rounded-xl border border-slate-200 shadow-sm hover:shadow-md transition-shadow">
<div className="flex items-center gap-3 mb-3">
<Settings className="w-5 h-5 text-emerald-500" />
<h4 className="text-lg font-bold text-slate-900 m-0">Code 128</h4>
</div>
<div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Logistics Universal</div>
<div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center">
<img src="/barcode-generator-preview.png" alt="Code 128 Barcode for Inventory and Shipping Labels" className="h-10 object-contain opacity-75 grayscale" width="200" height="40" />
</div>
<p className="text-sm text-slate-600 m-0">
Code 128 is a flexible barcode format that supports letters and numbers. It is commonly used in logistics, shipping, and internal tracking systems.
</p>
</div>
{/* Code 39 Card */}
<div className="bg-white p-6 rounded-xl border border-slate-200 shadow-sm hover:shadow-md transition-shadow">
<div className="flex items-center gap-3 mb-3">
<Factory className="w-5 h-5 text-orange-500" />
<h4 className="text-lg font-bold text-slate-900 m-0">Code 39</h4>
</div>
<div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Industrial Military</div>
<div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center">
<img src="/barcode-generator-preview.png" alt="Code 39 Barcode for Industrial Use" className="h-10 object-contain opacity-75 grayscale" width="200" height="40" />
</div>
<p className="text-sm text-slate-600 m-0">
The first alphanumeric barcode, Code 39 is still widely used in automotive and defense industries. It supports numbers and uppercase letters.
</p>
</div>
{/* MSI Card */}
<div className="bg-white p-6 rounded-xl border border-slate-200 shadow-sm hover:shadow-md transition-shadow">
<div className="flex items-center gap-3 mb-3">
<Layers className="w-5 h-5 text-purple-500" />
<h4 className="text-lg font-bold text-slate-900 m-0">MSI</h4>
</div>
<div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Inventory Shelves</div>
<div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center">
<img src="/barcode-generator-preview.png" alt="MSI Barcode for Inventory Management" className="h-10 object-contain opacity-75 grayscale" width="200" height="40" />
</div>
<p className="text-sm text-slate-600 m-0">
MSI (Modified Plessey) is often used for inventory control in retail environments, such as labeling shelves in supermarkets and warehouses.
</p>
</div>
{/* Pharmacode Card */}
<div className="bg-white p-6 rounded-xl border border-slate-200 shadow-sm hover:shadow-md transition-shadow">
<div className="flex items-center gap-3 mb-3">
<Activity className="w-5 h-5 text-red-500" />
<h4 className="text-lg font-bold text-slate-900 m-0">Pharmacode</h4>
</div>
<div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Pharma Packaging</div>
<div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center">
<img src="/barcode-generator-preview.png" alt="Pharmacode for Pharmaceutical Packaging" className="h-10 object-contain opacity-75 grayscale" width="200" height="40" />
</div>
<p className="text-sm text-slate-600 m-0">
Pharmacode is a specialized barcode standard used in the pharmaceutical industry for packaging control to prevent medication errors.
</p>
</div>
<div className="not-prose overflow-x-auto my-8">
<table className="w-full text-sm border-collapse rounded-xl overflow-hidden border border-slate-200">
<thead>
<tr className="bg-slate-900 text-white">
<th className="text-left p-3 font-semibold">Format</th>
<th className="text-left p-3 font-semibold">Use Case</th>
<th className="text-left p-3 font-semibold">Digits / Chars</th>
<th className="text-left p-3 font-semibold">Region</th>
</tr>
</thead>
<tbody>
<tr className="border-t border-slate-100 bg-white">
<td className="p-3 font-bold text-blue-700">EAN-13</td>
<td className="p-3 text-slate-600">Retail products, supermarkets</td>
<td className="p-3 text-slate-500 font-mono text-xs">13 numeric</td>
<td className="p-3 text-slate-600">Europe / Global</td>
</tr>
<tr className="border-t border-slate-100 bg-slate-50">
<td className="p-3 font-bold text-indigo-700">UPC-A</td>
<td className="p-3 text-slate-600">Retail products (North America)</td>
<td className="p-3 text-slate-500 font-mono text-xs">12 numeric</td>
<td className="p-3 text-slate-600">USA / Canada</td>
</tr>
<tr className="border-t border-slate-100 bg-white">
<td className="p-3 font-bold text-emerald-700">Code 128</td>
<td className="p-3 text-slate-600">Shipping, logistics, inventory</td>
<td className="p-3 text-slate-500 font-mono text-xs">Variable alphanumeric</td>
<td className="p-3 text-slate-600">Universal</td>
</tr>
<tr className="border-t border-slate-100 bg-slate-50">
<td className="p-3 font-bold text-orange-700">Code 39</td>
<td className="p-3 text-slate-600">Industrial, automotive, defense</td>
<td className="p-3 text-slate-500 font-mono text-xs">Variable alphanumeric</td>
<td className="p-3 text-slate-600">Industrial</td>
</tr>
<tr className="border-t border-slate-100 bg-white">
<td className="p-3 font-bold text-purple-700">MSI</td>
<td className="p-3 text-slate-600">Shelf / bin labeling, warehouse</td>
<td className="p-3 text-slate-500 font-mono text-xs">Variable numeric</td>
<td className="p-3 text-slate-600">Retail / Warehouse</td>
</tr>
<tr className="border-t border-slate-100 bg-slate-50">
<td className="p-3 font-bold text-red-700">Pharmacode</td>
<td className="p-3 text-slate-600">Pharmaceutical packaging</td>
<td className="p-3 text-slate-500 font-mono text-xs">3131071 numeric</td>
<td className="p-3 text-slate-600">Pharma</td>
</tr>
</tbody>
</table>
</div>
<BarcodeFormatPicker />
<h2>Why Use a Barcode Generator?</h2>
<p>Using a Barcode Generator offers several advantages:</p>
<div className="not-prose grid gap-4 mb-8">
@@ -244,8 +205,20 @@ export function BarcodeGuide() {
</ul>
<p>
A reliable <strong>Barcode Generator</strong> helps streamline these processes and improves efficiency.
For tracking QR codes alongside your barcodes, see our <Link href="/blog/qr-code-tracking-guide-2025" className="text-blue-600 hover:underline">QR code tracking guide</Link>.
</p>
<h2>Barcode Generator for Amazon Sellers</h2>
<p>
If you sell on Amazon, you will encounter two types of barcodes: <strong>GTINs</strong> (Global Trade Item Numbers, such as EAN-13 or UPC-A) required by Amazon to list products, and <strong>FNSKU</strong> barcodes that Amazon assigns to your specific seller account for FBA fulfillment.
</p>
<p>
Our barcode generator can create the <em>image</em> of an EAN-13 or UPC-A barcode if you already have a valid number. However, it cannot issue official GS1-registered numbers. To sell on Amazon with retail barcodes, you need to obtain a legitimate EAN or UPC number from <strong>GS1</strong> (the official barcode standards organization). Purchasing unofficial or recycled barcodes from third-party resellers often leads to listing suppression on Amazon.
</p>
<div className="not-prose bg-amber-50 border border-amber-200 rounded-xl p-4 my-4 text-sm text-amber-900">
<strong>Important for Amazon sellers:</strong> GS1 is the only authorized source for EAN/UPC numbers recognized by Amazon. Visit <strong>gs1.org</strong> to purchase official barcodes for your products. Use this generator to create barcode images once you have a valid number.
</div>
<h2>Understanding Check Digits</h2>
<p>
Most barcodes (like EAN and UPC) include a "Check Digit"the last number in the sequence. This digit is calculated mathematically from the other numbers to ensure the barcode is scanned correctly. Even if a barcode is slightly damaged or scratched, the scanner uses the check digit to verify the integrity of the data.
@@ -264,48 +237,44 @@ export function BarcodeGuide() {
<hr className="my-12 border-slate-200" />
<div className="flex items-center gap-3 mb-6 not-prose">
<HelpCircle className="w-6 h-6 text-blue-500" />
<h2 className="text-2xl font-bold text-slate-900 m-0">Frequently Asked Questions (FAQ)</h2>
</div>
<div className="not-prose space-y-8">
<div>
<h5 className="font-bold text-slate-900 text-lg mb-2"> What is a Barcode Generator?</h5>
<p className="text-slate-600">A Barcode Generator is an online tool that converts numbers or text into scannable barcode images that can be used for products, labels, and inventory systems.</p>
</div>
<div>
<h5 className="font-bold text-slate-900 text-lg mb-2"> Is this barcode generator free to use?</h5>
<p className="text-slate-600">Yes, our online barcode generator is completely free to use with no hidden costs or sign-ups required. You can generate, download, and print barcodes instantly.</p>
</div>
<div>
<h5 className="font-bold text-slate-900 text-lg mb-2"> Which barcode format should I use?</h5>
<p className="text-slate-600">
<strong>EAN-13:</strong> Standard for retail products in Europe and globally.<br />
<strong>UPC-A:</strong> Standard for retail products in USA/Canada.<br />
<strong>Code 128:</strong> Best for logistics, shipping, and internal tracking (supports letters & numbers).
</p>
</div>
<div>
<h5 className="font-bold text-slate-900 text-lg mb-2"> Can I download barcodes in vector format (SVG)?</h5>
<p className="text-slate-600">Yes! We offer <strong>SVG downloads</strong>. SVG files are vector-based, meaning they can be scaled to any size without losing qualityperfect for professional product packaging.</p>
</div>
<div>
<h5 className="font-bold text-slate-900 text-lg mb-2"> How do I generate a barcode online?</h5>
<p className="text-slate-600">To generate a barcode online, enter your product number or text, select the desired barcode format (such as EAN-13 or Code 128), and click the generate button. The barcode will be created instantly.</p>
</div>
<div>
<h5 className="font-bold text-slate-900 text-lg mb-2"> Are generated barcodes scannable?</h5>
<p className="text-slate-600">Yes, barcodes generated with a proper barcode generator are fully scannable. We generate standard-compliant barcodes readable by any standard optical or laser barcode scanner.</p>
</div>
<div>
<h5 className="font-bold text-slate-900 text-lg mb-2"> Can I use these barcodes for Amazon (EAN/UPC)?</h5>
<p className="text-slate-600">You can generate the <em>image</em> for Amazon here if you already have your EAN/UPC number. However, you cannot "create" a valid global EAN number hereyou must purchase those official numbers from GS1 to sell on major platforms like Amazon.</p>
</div>
<div>
<h5 className="font-bold text-slate-900 text-lg mb-2"> What is the difference between a barcode and a QR code?</h5>
<p className="text-slate-600">A barcode stores data horizontally (1D) and is mainly used for product IDs. A QR code stores data in 2D (matrix) and can hold much more information, such as URLs, vCards, or WiFi credentials.</p>
</div>
<div className="not-prose">
<FAQSection
title="Frequently Asked Questions"
items={[
{
question: 'What is a Barcode Generator?',
answer: 'A Barcode Generator is an online tool that converts numbers or text into scannable barcode images that can be used for products, labels, and inventory systems.',
},
{
question: 'Is this barcode generator free to use?',
answer: 'Yes, our online barcode generator is completely free to use with no hidden costs or sign-ups required. You can generate, download, and print barcodes instantly.',
},
{
question: 'Which barcode format should I use?',
answer: '<strong>EAN-13</strong> is the standard for retail products in Europe and globally. <strong>UPC-A</strong> is the standard for retail products in USA/Canada. <strong>Code 128</strong> is best for logistics, shipping, and internal tracking as it supports both letters and numbers. Use the format picker above to find the right one for your use case.',
},
{
question: 'Can I download barcodes in vector format (SVG)?',
answer: 'Yes — SVG downloads are available. SVG files are vector-based, meaning they can be scaled to any size without losing quality. This is ideal for professional product packaging and labels.',
},
{
question: 'How do I generate a barcode online?',
answer: 'Enter your product number or text, select the desired barcode format (such as EAN-13 or Code 128), and the barcode is generated instantly. You can then download it as PNG or SVG.',
},
{
question: 'Are generated barcodes scannable?',
answer: 'Yes. We generate standard-compliant barcodes that are readable by any standard optical or laser barcode scanner, including smartphone camera apps.',
},
{
question: 'Can I use these barcodes for Amazon (EAN/UPC)?',
answer: 'You can generate the barcode <em>image</em> here if you already have a valid EAN/UPC number. However, you cannot create a globally registered EAN/UPC number here — you must purchase official numbers from GS1 to list products on Amazon or in major retail systems.',
},
{
question: 'What is the difference between a barcode and a QR code?',
answer: 'A barcode stores data in one dimension (horizontal bars) and is mainly used for product identification. A QR code stores data in two dimensions (a matrix) and can hold much more information — URLs, contact details, WiFi credentials, and more.',
},
]}
/>
</div>
<div className="mt-12 p-6 bg-slate-900 rounded-xl text-white not-prose">

View File

@@ -11,9 +11,9 @@ import { generateSoftwareAppSchema, generateFaqSchema } from '@/lib/schema-utils
// SEO Optimized Metadata
export const metadata: Metadata = {
title: {
absolute: 'Barcode Generator Create Barcodes Online for Free',
absolute: 'Free Barcode Generator Online EAN, UPC, Code 128',
},
description: 'Use a free Barcode Generator to create scannable barcodes online. Supports EAN, UPC and Code 128 for products, labels and inventory.',
description: 'Free online barcode generator. Create EAN-13, UPC-A and Code 128 barcodes instantly. Download PNG or SVG. No signup required.',
keywords: ['barcode generator', 'online barcode maker', 'create barcode free', 'ean-13 generator', 'upc-a generator', 'code 128 generator', 'barcode creator', 'printable barcodes'],
alternates: {
canonical: 'https://www.qrmaster.net/tools/barcode-generator',

View File

@@ -1,78 +1,78 @@
import { notFound } from "next/navigation";
import {
buildUseCaseMetadata,
UseCasePageTemplate,
} from "@/components/marketing/UseCasePageTemplate";
import {
allUseCases,
getUseCasePage,
} from "@/lib/growth-pages";
export function generateStaticParams() {
return allUseCases.map((item) => ({
slug: item.slug,
}));
}
export function generateMetadata({ params }: { params: { slug: string } }) {
const page = getUseCasePage(params.slug);
if (!page) {
return {};
}
return buildUseCaseMetadata({
title: page.title,
description: page.metaDescription,
canonicalPath: page.href,
});
}
export default function UseCaseDetailPage({
params,
}: {
params: { slug: string };
}) {
const page = getUseCasePage(params.slug);
if (!page) {
notFound();
}
return (
<UseCasePageTemplate
title={page.title}
description={page.metaDescription}
eyebrow={page.eyebrow}
intro={page.intro}
pageType="use_case"
cluster={page.cluster}
useCase={page.slug}
breadcrumbs={[
{ name: "Home", url: "/" },
{ name: "Use Cases", url: "/use-cases" },
{ name: page.title, url: page.href },
]}
answer={page.answer}
whenToUse={page.whenToUse}
comparisonItems={page.comparisonItems}
howToSteps={page.howToSteps}
primaryCta={{
href: page.parentHref,
label: page.ctaLabel,
}}
secondaryCta={{
href: "/use-cases",
label: "Explore more use cases",
}}
workflowTitle={page.workflowTitle}
workflowIntro={page.workflowIntro}
workflowCards={page.workflowCards}
checklistTitle={page.checklistTitle}
checklist={page.checklist}
supportLinks={page.supportLinks}
faq={page.faq}
/>
);
}
import { notFound } from "next/navigation";
import {
buildUseCaseMetadata,
UseCasePageTemplate,
} from "@/components/marketing/UseCasePageTemplate";
import {
allUseCases,
getUseCasePage,
} from "@/lib/growth-pages";
export function generateStaticParams() {
return allUseCases.map((item) => ({
slug: item.slug,
}));
}
export function generateMetadata({ params }: { params: { slug: string } }) {
const page = getUseCasePage(params.slug);
if (!page) {
return {};
}
return buildUseCaseMetadata({
title: page.title,
description: page.metaDescription,
canonicalPath: page.href,
});
}
export default function UseCaseDetailPage({
params,
}: {
params: { slug: string };
}) {
const page = getUseCasePage(params.slug);
if (!page) {
notFound();
}
return (
<UseCasePageTemplate
title={page.title}
description={page.metaDescription}
eyebrow={page.eyebrow}
intro={page.intro}
pageType="use_case"
cluster={page.cluster}
useCase={page.slug}
breadcrumbs={[
{ name: "Home", url: "/" },
{ name: "Use Cases", url: "/use-cases" },
{ name: page.title, url: page.href },
]}
answer={page.answer}
whenToUse={page.whenToUse}
comparisonItems={page.comparisonItems}
howToSteps={page.howToSteps}
primaryCta={{
href: page.parentHref,
label: page.ctaLabel,
}}
secondaryCta={{
href: "/use-cases",
label: "Explore more use cases",
}}
workflowTitle={page.workflowTitle}
workflowIntro={page.workflowIntro}
workflowCards={page.workflowCards}
checklistTitle={page.checklistTitle}
checklist={page.checklist}
supportLinks={page.supportLinks}
faq={page.faq}
/>
);
}

View File

@@ -1,304 +1,304 @@
import type { Metadata } from "next";
import Link from "next/link";
import {
ArrowRight,
Compass,
LibraryBig,
Link2,
Route,
Sparkles,
} from "lucide-react";
import Breadcrumbs, { BreadcrumbItem } from "@/components/Breadcrumbs";
import SeoJsonLd from "@/components/SeoJsonLd";
import {
MarketingPageTracker,
TrackedCtaLink,
} from "@/components/marketing/MarketingAnalytics";
import { Button } from "@/components/ui/Button";
import { Card } from "@/components/ui/Card";
import {
allUseCases,
commercialPages,
featuredUseCases,
supportResources,
upcomingUseCaseIdeas,
} from "@/lib/growth-pages";
import { breadcrumbSchema } from "@/lib/schema";
export const metadata: Metadata = {
title: {
absolute: "QR Code Use Cases for Business | QR Master",
},
description:
"Explore QR code use cases for restaurants, events, business cards, and campaign workflows built around dynamic updates and tracking.",
alternates: {
canonical: "https://www.qrmaster.net/use-cases",
languages: {
"x-default": "https://www.qrmaster.net/use-cases",
en: "https://www.qrmaster.net/use-cases",
},
},
openGraph: {
title: "QR Code Use Cases for Business | QR Master",
description:
"Explore QR code use cases for restaurants, events, business cards, and campaign workflows built around dynamic updates and tracking.",
url: "https://www.qrmaster.net/use-cases",
type: "website",
images: ["/og-image.png"],
},
twitter: {
title: "QR Code Use Cases for Business | QR Master",
description:
"Explore QR code use cases for restaurants, events, business cards, and campaign workflows built around dynamic updates and tracking.",
},
};
export default function UseCasesHubPage() {
const breadcrumbItems: BreadcrumbItem[] = [
{ name: "Home", url: "/" },
{ name: "Use Cases", url: "/use-cases" },
];
return (
<>
<SeoJsonLd data={[breadcrumbSchema(breadcrumbItems)]} />
<MarketingPageTracker pageType="use_case_hub" cluster="all-use-cases" />
<div className="min-h-screen bg-white">
<section className="relative overflow-hidden bg-gradient-to-br from-slate-950 via-blue-950 to-cyan-950 text-white">
<div className="absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(125,211,252,0.18),transparent_34%),radial-gradient(circle_at_right,rgba(255,255,255,0.06),transparent_28%)]" />
<div className="relative container mx-auto max-w-7xl px-4 py-20 sm:px-6 lg:px-8">
<Breadcrumbs
items={breadcrumbItems}
className="[&_a]:text-blue-100/80 [&_a:hover]:text-white [&_span]:text-blue-100/80 [&_[aria-current=page]]:text-white"
/>
<div className="grid gap-12 lg:grid-cols-[minmax(0,1.2fr)_minmax(320px,0.8fr)] lg:items-center">
<div className="space-y-8">
<div className="inline-flex items-center gap-2 rounded-full border border-white/15 bg-white/10 px-4 py-2 text-sm font-semibold text-cyan-100 shadow-lg shadow-cyan-950/30 backdrop-blur">
<Sparkles className="h-4 w-4" />
<span>Commercial use-case hub</span>
</div>
<div className="space-y-5">
<h1 className="max-w-4xl text-4xl font-bold tracking-tight text-white md:text-5xl lg:text-6xl">
QR code use cases that fit real business workflows
</h1>
<p className="max-w-3xl text-lg leading-8 text-blue-50/88 md:text-xl">
This hub focuses on workflows where dynamic updates and
measurement matter. It is not a list of random QR ideas. It
is the commercial layer between QR Master's product pages,
tools, and editorial content.
</p>
</div>
<div className="grid gap-3 text-sm text-blue-50/80 sm:grid-cols-2">
{[
"Use-case pages map back to a clear commercial parent.",
"Each workflow is written for practical deployment, not filler traffic.",
"Support resources reinforce the wedge around dynamic and trackable QR flows.",
"The next cluster expansion will build on measurable routing and internal links.",
].map((line) => (
<div
key={line}
className="flex items-start gap-3 rounded-2xl border border-white/10 bg-white/5 px-4 py-3 backdrop-blur-sm"
>
<Route className="mt-0.5 h-4 w-4 shrink-0 text-cyan-300" />
<span>{line}</span>
</div>
))}
</div>
<div className="flex flex-col gap-4 sm:flex-row">
<TrackedCtaLink
href={featuredUseCases[0].href}
ctaLabel="Explore restaurant menu QR codes"
ctaLocation="hero_primary"
pageType="use_case_hub"
cluster="all-use-cases"
>
<Button size="lg" className="w-full bg-white px-8 py-4 text-slate-950 hover:bg-slate-100 sm:w-auto">
Explore featured workflows
</Button>
</TrackedCtaLink>
<TrackedCtaLink
href="/qr-code-for-marketing-campaigns"
ctaLabel="View marketing campaign QR page"
ctaLocation="hero_secondary"
pageType="use_case_hub"
cluster="all-use-cases"
>
<Button
variant="outline"
size="lg"
className="w-full border-white/30 bg-white/5 px-8 py-4 text-white hover:bg-white/10 sm:w-auto"
>
See campaign workflows
</Button>
</TrackedCtaLink>
</div>
</div>
<Card className="border-white/10 bg-white/10 p-8 text-white shadow-2xl shadow-slate-950/30 backdrop-blur">
<div className="space-y-5">
<div className="flex items-center gap-3">
<Compass className="h-5 w-5 text-cyan-300" />
<h2 className="text-2xl font-bold">How to use this hub</h2>
</div>
<div className="space-y-4 text-sm leading-6 text-blue-50/82">
<p>
Start with the workflow problem, not the QR format. If the
printed code needs to survive destination changes or you
need proof of performance, begin with the use case that
matches that job.
</p>
<p>
Each page below links back to the best product parent,
forward to related workflows, and sideways to educational
resources that help you deploy the QR well.
</p>
</div>
</div>
</Card>
</div>
</div>
</section>
<section className="py-16">
<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">
All live use cases
</div>
<h2 className="mt-3 text-3xl font-bold text-slate-900">
Every currently published workflow route
</h2>
<p className="mt-4 text-lg leading-8 text-slate-600">
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 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">
{page.cluster}
</div>
<h3 className="mt-4 text-2xl font-bold text-slate-900">
{page.title}
</h3>
<p className="mt-4 flex-1 text-base leading-7 text-slate-600">
{page.summary}
</p>
<div className="mt-6 flex items-center justify-between rounded-2xl bg-slate-50 px-4 py-3 text-sm text-slate-600">
<span>Primary parent: {page.parentTitle}</span>
<ArrowRight className="h-4 w-4 text-blue-700 transition-transform group-hover:translate-x-1" />
</div>
</Card>
</Link>
))}
</div>
</div>
</section>
<section className="bg-slate-50 py-16">
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="grid gap-8 lg:grid-cols-[minmax(0,1fr)_minmax(0,0.95fr)]">
<Card className="rounded-3xl border-slate-200 bg-white p-8 shadow-sm">
<div className="flex items-center gap-3">
<LibraryBig className="h-5 w-5 text-blue-700" />
<h2 className="text-2xl font-bold text-slate-900">
Commercial pages that anchor the hub
</h2>
</div>
<div className="mt-6 grid gap-4 md:grid-cols-2">
{commercialPages.map((page) => (
<Link
key={page.href}
href={page.href}
className="rounded-2xl border border-slate-200 p-4 transition-colors hover:border-blue-200 hover:bg-blue-50/60"
>
<div className={`h-1.5 rounded-full bg-gradient-to-r ${page.accent}`} />
<div className="mt-4 text-lg font-semibold text-slate-900">
{page.title}
</div>
<p className="mt-2 text-sm leading-6 text-slate-600">
{page.description}
</p>
</Link>
))}
</div>
</Card>
<Card className="rounded-3xl border-slate-200 bg-slate-950 p-8 text-white shadow-xl shadow-slate-200">
<div className="flex items-center gap-3">
<Link2 className="h-5 w-5 text-cyan-300" />
<h2 className="text-2xl font-bold">Support resources</h2>
</div>
<div className="mt-6 space-y-4">
{supportResources.map((resource) => (
<Link
key={resource.href}
href={resource.href}
className="block rounded-2xl border border-white/10 bg-white/5 p-4 transition-colors hover:bg-white/10"
>
<div className="text-lg font-semibold text-white">
{resource.title}
</div>
<p className="mt-2 text-sm leading-6 text-blue-50/78">
{resource.description}
</p>
</Link>
))}
</div>
</Card>
</div>
</div>
</section>
<section className="py-16">
<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">
Next cluster candidates
</div>
<h2 className="mt-3 text-3xl font-bold text-slate-900">
What follows after the first use-case wave
</h2>
<p className="mt-4 text-lg leading-8 text-slate-600">
These are not published use-case routes yet. They are the next
practical cluster expansions once the first hub and CTA layer are
established.
</p>
</div>
<div className="grid gap-6 md:grid-cols-3">
{upcomingUseCaseIdeas.map((item) => (
<Card
key={item.title}
className="rounded-3xl border-dashed border-slate-300 bg-slate-50 p-7"
>
<div className="text-xl font-semibold text-slate-900">
{item.title}
</div>
<p className="mt-3 text-base leading-7 text-slate-600">
{item.description}
</p>
<div className="mt-5 text-sm font-semibold text-blue-700">
Anchored by {item.href.replace("/", "")}
</div>
</Card>
))}
</div>
</div>
</section>
</div>
</>
);
}
import type { Metadata } from "next";
import Link from "next/link";
import {
ArrowRight,
Compass,
LibraryBig,
Link2,
Route,
Sparkles,
} from "lucide-react";
import Breadcrumbs, { BreadcrumbItem } from "@/components/Breadcrumbs";
import SeoJsonLd from "@/components/SeoJsonLd";
import {
MarketingPageTracker,
TrackedCtaLink,
} from "@/components/marketing/MarketingAnalytics";
import { Button } from "@/components/ui/Button";
import { Card } from "@/components/ui/Card";
import {
allUseCases,
commercialPages,
featuredUseCases,
supportResources,
upcomingUseCaseIdeas,
} from "@/lib/growth-pages";
import { breadcrumbSchema } from "@/lib/schema";
export const metadata: Metadata = {
title: {
absolute: "QR Code Use Cases for Business | QR Master",
},
description:
"Explore QR code use cases for restaurants, events, business cards, and campaign workflows built around dynamic updates and tracking.",
alternates: {
canonical: "https://www.qrmaster.net/use-cases",
languages: {
"x-default": "https://www.qrmaster.net/use-cases",
en: "https://www.qrmaster.net/use-cases",
},
},
openGraph: {
title: "QR Code Use Cases for Business | QR Master",
description:
"Explore QR code use cases for restaurants, events, business cards, and campaign workflows built around dynamic updates and tracking.",
url: "https://www.qrmaster.net/use-cases",
type: "website",
images: ["/og-image.png"],
},
twitter: {
title: "QR Code Use Cases for Business | QR Master",
description:
"Explore QR code use cases for restaurants, events, business cards, and campaign workflows built around dynamic updates and tracking.",
},
};
export default function UseCasesHubPage() {
const breadcrumbItems: BreadcrumbItem[] = [
{ name: "Home", url: "/" },
{ name: "Use Cases", url: "/use-cases" },
];
return (
<>
<SeoJsonLd data={[breadcrumbSchema(breadcrumbItems)]} />
<MarketingPageTracker pageType="use_case_hub" cluster="all-use-cases" />
<div className="min-h-screen bg-white">
<section className="relative overflow-hidden bg-gradient-to-br from-slate-950 via-blue-950 to-cyan-950 text-white">
<div className="absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(125,211,252,0.18),transparent_34%),radial-gradient(circle_at_right,rgba(255,255,255,0.06),transparent_28%)]" />
<div className="relative container mx-auto max-w-7xl px-4 py-20 sm:px-6 lg:px-8">
<Breadcrumbs
items={breadcrumbItems}
className="[&_a]:text-blue-100/80 [&_a:hover]:text-white [&_span]:text-blue-100/80 [&_[aria-current=page]]:text-white"
/>
<div className="grid gap-12 lg:grid-cols-[minmax(0,1.2fr)_minmax(320px,0.8fr)] lg:items-center">
<div className="space-y-8">
<div className="inline-flex items-center gap-2 rounded-full border border-white/15 bg-white/10 px-4 py-2 text-sm font-semibold text-cyan-100 shadow-lg shadow-cyan-950/30 backdrop-blur">
<Sparkles className="h-4 w-4" />
<span>Commercial use-case hub</span>
</div>
<div className="space-y-5">
<h1 className="max-w-4xl text-4xl font-bold tracking-tight text-white md:text-5xl lg:text-6xl">
QR code use cases that fit real business workflows
</h1>
<p className="max-w-3xl text-lg leading-8 text-blue-50/88 md:text-xl">
This hub focuses on workflows where dynamic updates and
measurement matter. It is not a list of random QR ideas. It
is the commercial layer between QR Master's product pages,
tools, and editorial content.
</p>
</div>
<div className="grid gap-3 text-sm text-blue-50/80 sm:grid-cols-2">
{[
"Use-case pages map back to a clear commercial parent.",
"Each workflow is written for practical deployment, not filler traffic.",
"Support resources reinforce the wedge around dynamic and trackable QR flows.",
"The next cluster expansion will build on measurable routing and internal links.",
].map((line) => (
<div
key={line}
className="flex items-start gap-3 rounded-2xl border border-white/10 bg-white/5 px-4 py-3 backdrop-blur-sm"
>
<Route className="mt-0.5 h-4 w-4 shrink-0 text-cyan-300" />
<span>{line}</span>
</div>
))}
</div>
<div className="flex flex-col gap-4 sm:flex-row">
<TrackedCtaLink
href={featuredUseCases[0].href}
ctaLabel="Explore restaurant menu QR codes"
ctaLocation="hero_primary"
pageType="use_case_hub"
cluster="all-use-cases"
>
<Button size="lg" className="w-full bg-white px-8 py-4 text-slate-950 hover:bg-slate-100 sm:w-auto">
Explore featured workflows
</Button>
</TrackedCtaLink>
<TrackedCtaLink
href="/qr-code-for-marketing-campaigns"
ctaLabel="View marketing campaign QR page"
ctaLocation="hero_secondary"
pageType="use_case_hub"
cluster="all-use-cases"
>
<Button
variant="outline"
size="lg"
className="w-full border-white/30 bg-white/5 px-8 py-4 text-white hover:bg-white/10 sm:w-auto"
>
See campaign workflows
</Button>
</TrackedCtaLink>
</div>
</div>
<Card className="border-white/10 bg-white/10 p-8 text-white shadow-2xl shadow-slate-950/30 backdrop-blur">
<div className="space-y-5">
<div className="flex items-center gap-3">
<Compass className="h-5 w-5 text-cyan-300" />
<h2 className="text-2xl font-bold">How to use this hub</h2>
</div>
<div className="space-y-4 text-sm leading-6 text-blue-50/82">
<p>
Start with the workflow problem, not the QR format. If the
printed code needs to survive destination changes or you
need proof of performance, begin with the use case that
matches that job.
</p>
<p>
Each page below links back to the best product parent,
forward to related workflows, and sideways to educational
resources that help you deploy the QR well.
</p>
</div>
</div>
</Card>
</div>
</div>
</section>
<section className="py-16">
<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">
All live use cases
</div>
<h2 className="mt-3 text-3xl font-bold text-slate-900">
Every currently published workflow route
</h2>
<p className="mt-4 text-lg leading-8 text-slate-600">
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 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">
{page.cluster}
</div>
<h3 className="mt-4 text-2xl font-bold text-slate-900">
{page.title}
</h3>
<p className="mt-4 flex-1 text-base leading-7 text-slate-600">
{page.summary}
</p>
<div className="mt-6 flex items-center justify-between rounded-2xl bg-slate-50 px-4 py-3 text-sm text-slate-600">
<span>Primary parent: {page.parentTitle}</span>
<ArrowRight className="h-4 w-4 text-blue-700 transition-transform group-hover:translate-x-1" />
</div>
</Card>
</Link>
))}
</div>
</div>
</section>
<section className="bg-slate-50 py-16">
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="grid gap-8 lg:grid-cols-[minmax(0,1fr)_minmax(0,0.95fr)]">
<Card className="rounded-3xl border-slate-200 bg-white p-8 shadow-sm">
<div className="flex items-center gap-3">
<LibraryBig className="h-5 w-5 text-blue-700" />
<h2 className="text-2xl font-bold text-slate-900">
Commercial pages that anchor the hub
</h2>
</div>
<div className="mt-6 grid gap-4 md:grid-cols-2">
{commercialPages.map((page) => (
<Link
key={page.href}
href={page.href}
className="rounded-2xl border border-slate-200 p-4 transition-colors hover:border-blue-200 hover:bg-blue-50/60"
>
<div className={`h-1.5 rounded-full bg-gradient-to-r ${page.accent}`} />
<div className="mt-4 text-lg font-semibold text-slate-900">
{page.title}
</div>
<p className="mt-2 text-sm leading-6 text-slate-600">
{page.description}
</p>
</Link>
))}
</div>
</Card>
<Card className="rounded-3xl border-slate-200 bg-slate-950 p-8 text-white shadow-xl shadow-slate-200">
<div className="flex items-center gap-3">
<Link2 className="h-5 w-5 text-cyan-300" />
<h2 className="text-2xl font-bold">Support resources</h2>
</div>
<div className="mt-6 space-y-4">
{supportResources.map((resource) => (
<Link
key={resource.href}
href={resource.href}
className="block rounded-2xl border border-white/10 bg-white/5 p-4 transition-colors hover:bg-white/10"
>
<div className="text-lg font-semibold text-white">
{resource.title}
</div>
<p className="mt-2 text-sm leading-6 text-blue-50/78">
{resource.description}
</p>
</Link>
))}
</div>
</Card>
</div>
</div>
</section>
<section className="py-16">
<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">
Next cluster candidates
</div>
<h2 className="mt-3 text-3xl font-bold text-slate-900">
What follows after the first use-case wave
</h2>
<p className="mt-4 text-lg leading-8 text-slate-600">
These are not published use-case routes yet. They are the next
practical cluster expansions once the first hub and CTA layer are
established.
</p>
</div>
<div className="grid gap-6 md:grid-cols-3">
{upcomingUseCaseIdeas.map((item) => (
<Card
key={item.title}
className="rounded-3xl border-dashed border-slate-300 bg-slate-50 p-7"
>
<div className="text-xl font-semibold text-slate-900">
{item.title}
</div>
<p className="mt-3 text-base leading-7 text-slate-600">
{item.description}
</p>
<div className="mt-5 text-sm font-semibold text-blue-700">
Anchored by {item.href.replace("/", "")}
</div>
</Card>
))}
</div>
</div>
</section>
</div>
</>
);
}