This commit is contained in:
Timo Knuth
2026-03-12 15:54:56 +01:00
parent 3c8e6bd19f
commit d47108d27c
16 changed files with 3826 additions and 5316 deletions

View File

@@ -1,234 +1,243 @@
import React from 'react';
import type { Metadata } from 'next';
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 & Bulk QR', 60);
const description = truncateAtWord(
'All answers: dynamic QR, security, analytics, bulk, events & print.',
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 - Dynamic QR Code Generator and Analytics Platform',
},
],
},
twitter: {
title,
description,
},
};
}
import Link from 'next/link';
// Extended type for UI with Rich Text support
type FAQItemWithRichText = {
question: string;
answer: string; // Plain text for Schema
answerRich?: React.ReactNode; // JSX for UI
};
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 reprinting. Key benefits: Update the destination anytime, Track scans (time, device, location), Pause/disable campaigns.',
answerRich: (
<>
A dynamic QR code points to a redirect URL, so you can change the final destination later without reprinting.
<br /><br />
<strong>Key benefits:</strong>
<ul className="list-disc pl-5 mt-2 space-y-1">
<li>Update the destination anytime</li>
<li>Track scans (time, device, location) via <Link href="/guide/tracking-analytics" className="text-blue-600 hover:underline">Analytics</Link></li>
<li>Pause/disable campaigns without changing the printed code</li>
</ul>
</>
),
},
{
question: 'How do I track QR scans?',
answer: 'QR Master tracks scan events in real-time via the short URL redirect. Metrics included: Total and unique scans, Device type, Geographic location, and Time of day.',
answerRich: (
<>
QR Master tracks scan events in real-time via the short URL redirect.
<br /><br />
<strong>Metrics included:</strong>
<ul className="list-disc pl-5 mt-2 space-y-1">
<li>Total and unique scans</li>
<li>Device type (iOS, Android, Desktop)</li>
<li>Geographic location (Country, City)</li>
<li>Time of day</li>
</ul>
<br />
<Link href="/qr-code-tracking" className="text-blue-600 hover:underline font-medium">Learn more about Tracking </Link>
</>
),
},
{
question: 'What security measures are in place?',
answer: 'We prioritize data security through standard industry practices. Security features: HTTPS/TLS encryption, Automated link validation, and Rate limiting.',
answerRich: (
<>
We prioritize data security through standard industry practices.
<br /><br />
<strong>Security features:</strong>
<ul className="list-disc pl-5 mt-2 space-y-1">
<li>HTTPS/TLS encryption for all connections</li>
<li>Automated link validation to prevent malicious redirects</li>
<li>Rate limiting to prevent abuse</li>
</ul>
</>
),
},
{
question: 'Bulk QR codes: Print, Marketing, and API?',
answer: 'You can generate thousands of codes via CSV upload or API for scalable campaigns. Features: CSV Upload (1,000+ codes), Customization, and API access.',
answerRich: (
<>
You can generate thousands of codes via CSV upload or API for scalable campaigns.
<br /><br />
<strong>Features:</strong>
<ul className="list-disc pl-5 mt-2 space-y-1">
<li><strong>CSV Upload:</strong> Create up to 1,000 codes at once (<Link href="/bulk-qr-code-generator" className="text-blue-600 hover:underline">Bulk Generator</Link>)</li>
<li><strong>Customization:</strong> Apply branding to all batch codes</li>
<li><strong>API:</strong> Programmatic generation for internal systems</li>
</ul>
</>
),
},
{
question: 'What are the best practices for printing QR codes?',
answer: 'Ensure high scannability by following these rules: Minimum size 2x2 cm, High contrast (dark on light), Vector formats (SVG/EPS) for large print, and maintain a quiet zone border.',
answerRich: (
<>
Ensure high scannability by following these rules:
<br /><br />
<strong>Print Guidelines:</strong>
<ul className="list-disc pl-5 mt-2 space-y-1">
<li><strong>Size:</strong> Minimum 2x2 cm (0.8x0.8 inch) for close range</li>
<li><strong>Format:</strong> Use <span className="font-semibold">SVG/EPS</span> (Vector) for professional print quality</li>
<li><strong>Contrast:</strong> Always use dark foreground on light background</li>
<li><strong>Quiet Zone:</strong> Leave a margin around the code</li>
</ul>
</>
),
},
{
question: 'Is the service GDPR aligned?',
answer: 'Yes, we minimize data collection to ensure privacy compliance. Privacy measures: IP anonymization, No PII storage, and EU-based servers.',
answerRich: (
<>
Yes, we minimize data collection to ensure privacy compliance.
<br /><br />
<strong>Privacy measures:</strong>
<ul className="list-disc pl-5 mt-2 space-y-1">
<li>IP addresses are anonymized or hashed</li>
<li>No personal data (PII) is stored from scanners</li>
<li>Servers located in EU regions (for EU customers)</li>
</ul>
<br />
<Link href="/privacy" className="text-blue-600 hover:underline font-medium">Read Privacy Policy </Link>
</>
),
},
{
question: 'Dynamic vs Static QR Codes?',
answer: 'Static codes are fixed forever; Dynamic codes can be edited and tracked. Comparison: Static (free, permanent, no tracking) vs Dynamic (editable, analytics, campaign logic).',
answerRich: (
<>
Static codes are fixed forever; Dynamic codes can be edited and tracked.
<br /><br />
<strong>Comparison:</strong>
<ul className="list-disc pl-5 mt-2 space-y-1">
<li><strong>Static:</strong> content embedded directly, no tracking, free forever</li>
<li><strong>Dynamic:</strong> redirect link, editable destination, scan analytics</li>
</ul>
<br />
<Link href="/dynamic-qr-code-generator" className="text-blue-600 hover:underline font-medium">Create Dynamic QR </Link>
</>
),
},
];
export default function FAQPage() {
return (
<>
<SeoJsonLd data={faqPageSchema(faqs.map(({ question, answer }) => ({ question, answer })))} />
<div className="py-20 bg-gradient-to-b from-gray-50 to-white">
<div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto">
<div className="text-center mb-16">
<h1 className="text-4xl lg:text-5xl font-bold text-gray-900 mb-6">
Frequently Asked Questions
</h1>
<p className="text-xl text-gray-600 mb-4">
Everything you need to know about dynamic QR codes, security, analytics, bulk generation, events, and print quality.
</p>
<p className="text-sm text-gray-500">
Last updated: January 25, 2025
</p>
</div>
<div className="space-y-6">
{faqs.map((faq, index) => (
<Card key={index} className="border-l-4 border-blue-500">
<CardContent className="p-8">
<h2 className="text-2xl font-semibold mb-4 text-gray-900">
{faq.question}
</h2>
<div className="text-lg text-gray-700 leading-relaxed">
{faq.answerRich || faq.answer}
</div>
</CardContent>
</Card>
))}
</div>
<div className="mt-16 bg-blue-50 border-l-4 border-blue-500 p-8 rounded-r-lg">
<h2 className="text-2xl font-bold mb-4 text-gray-900">
Still have questions?
</h2>
<p className="text-lg text-gray-700 mb-6 leading-relaxed">
Our support team is here to help. Contact us at{' '}
<ObfuscatedMailto email="support@qrmaster.net" className="text-blue-600 hover:text-blue-700 font-semibold" />{' '}
or reach out through our live chat.
</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>
</>
);
}