AEO / SEO
|
|
@ -473,3 +473,10 @@ For support, email support@qrmaster.net or open an issue on GitHub.
|
||||||
---
|
---
|
||||||
|
|
||||||
Built with ❤️ by QR Master Team
|
Built with ❤️ by QR Master Team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Führe diese im Terminal aus:
|
||||||
|
|
||||||
|
IndexNow (Bing/Yandex + Partner): npm run submit:indexnow
|
||||||
|
Google Indexing API: npm run trigger:indexing
|
||||||
|
|
@ -20,6 +20,25 @@ const nextConfig = {
|
||||||
pagesBufferLength: 2,
|
pagesBufferLength: 2,
|
||||||
},
|
},
|
||||||
poweredByHeader: false,
|
poweredByHeader: false,
|
||||||
|
async redirects() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
source: '/tools/phone-qr-code',
|
||||||
|
destination: '/tools/call-qr-code-generator',
|
||||||
|
permanent: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: '/barcode-generator',
|
||||||
|
destination: '/tools/barcode-generator',
|
||||||
|
permanent: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: '/bar-code-generator',
|
||||||
|
destination: '/tools/barcode-generator',
|
||||||
|
permanent: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nextConfig;
|
export default nextConfig;
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@
|
||||||
"@types/react": "^18.2.45",
|
"@types/react": "^18.2.45",
|
||||||
"@types/react-dom": "^18.2.18",
|
"@types/react-dom": "^18.2.18",
|
||||||
"autoprefixer": "^10.4.16",
|
"autoprefixer": "^10.4.16",
|
||||||
|
"cross-env": "^10.1.0",
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^8.56.0",
|
||||||
"eslint-config-next": "^16.1.1",
|
"eslint-config-next": "^16.1.1",
|
||||||
"next-sitemap": "^4.2.3",
|
"next-sitemap": "^4.2.3",
|
||||||
|
|
@ -1422,6 +1423,13 @@
|
||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@epic-web/invariant": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@esbuild/aix-ppc64": {
|
"node_modules/@esbuild/aix-ppc64": {
|
||||||
"version": "0.25.12",
|
"version": "0.25.12",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
|
||||||
|
|
@ -5845,6 +5853,24 @@
|
||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cross-env": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@epic-web/invariant": "^1.0.0",
|
||||||
|
"cross-spawn": "^7.0.6"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"cross-env": "dist/bin/cross-env.js",
|
||||||
|
"cross-env-shell": "dist/bin/cross-env-shell.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev -p 3050",
|
"dev": "next dev -p 3050",
|
||||||
"build": "prisma generate && next build",
|
"build": "prisma generate && cross-env NODE_OPTIONS='--max-old-space-size=4096' next build",
|
||||||
"trigger:indexing": "tsx scripts/trigger-indexing.ts",
|
"trigger:indexing": "tsx scripts/trigger-indexing.ts",
|
||||||
"submit:indexnow": "tsx scripts/submit-indexnow.ts",
|
"submit:indexnow": "tsx scripts/submit-indexnow.ts",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
|
|
@ -82,6 +82,7 @@
|
||||||
"@types/react": "^18.2.45",
|
"@types/react": "^18.2.45",
|
||||||
"@types/react-dom": "^18.2.18",
|
"@types/react-dom": "^18.2.18",
|
||||||
"autoprefixer": "^10.4.16",
|
"autoprefixer": "^10.4.16",
|
||||||
|
"cross-env": "^10.1.0",
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^8.56.0",
|
||||||
"eslint-config-next": "^16.1.1",
|
"eslint-config-next": "^16.1.1",
|
||||||
"next-sitemap": "^4.2.3",
|
"next-sitemap": "^4.2.3",
|
||||||
|
|
@ -96,4 +97,4 @@
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
After Width: | Height: | Size: 657 KiB |
|
After Width: | Height: | Size: 516 KiB |
|
After Width: | Height: | Size: 423 KiB |
|
After Width: | Height: | Size: 650 KiB |
|
After Width: | Height: | Size: 646 KiB |
|
After Width: | Height: | Size: 492 KiB |
|
After Width: | Height: | Size: 700 KiB |
|
After Width: | Height: | Size: 422 KiB |
|
|
@ -50,7 +50,7 @@ export default function MarketingLayout({
|
||||||
{ name: 'WhatsApp', description: 'Start a chat', href: '/tools/whatsapp-qr-code', icon: MessageCircle, color: 'text-green-500', bgColor: 'bg-green-50' },
|
{ name: 'WhatsApp', description: 'Start a chat', href: '/tools/whatsapp-qr-code', icon: MessageCircle, color: 'text-green-500', bgColor: 'bg-green-50' },
|
||||||
{ name: 'Email', description: 'Compose an email', href: '/tools/email-qr-code', icon: Mail, color: 'text-amber-500', bgColor: 'bg-amber-50' },
|
{ name: 'Email', description: 'Compose an email', href: '/tools/email-qr-code', icon: Mail, color: 'text-amber-500', bgColor: 'bg-amber-50' },
|
||||||
{ name: 'SMS', description: 'Send a text message', href: '/tools/sms-qr-code', icon: MessageSquare, color: 'text-cyan-500', bgColor: 'bg-cyan-50' },
|
{ name: 'SMS', description: 'Send a text message', href: '/tools/sms-qr-code', icon: MessageSquare, color: 'text-cyan-500', bgColor: 'bg-cyan-50' },
|
||||||
{ name: 'Phone', description: 'Start a call', href: '/tools/phone-qr-code', icon: Phone, color: 'text-violet-500', bgColor: 'bg-violet-50' },
|
{ name: 'Call', description: 'Start a call', href: '/tools/call-qr-code-generator', icon: Phone, color: 'text-violet-500', bgColor: 'bg-violet-50' },
|
||||||
{ name: 'Event', description: 'Add calendar event', href: '/tools/event-qr-code', icon: Calendar, color: 'text-red-500', bgColor: 'bg-red-50' },
|
{ name: 'Event', description: 'Add calendar event', href: '/tools/event-qr-code', icon: Calendar, color: 'text-red-500', bgColor: 'bg-red-50' },
|
||||||
{ name: 'Location', description: 'Share a place', href: '/tools/geolocation-qr-code', icon: MapPin, color: 'text-emerald-500', bgColor: 'bg-emerald-50' },
|
{ name: 'Location', description: 'Share a place', href: '/tools/geolocation-qr-code', icon: MapPin, color: 'text-emerald-500', bgColor: 'bg-emerald-50' },
|
||||||
{ name: 'Facebook', description: 'Facebook profile/page', href: '/tools/facebook-qr-code', icon: Facebook, color: 'text-blue-600', bgColor: 'bg-blue-50' },
|
{ name: 'Facebook', description: 'Facebook profile/page', href: '/tools/facebook-qr-code', icon: Facebook, color: 'text-blue-600', bgColor: 'bg-blue-50' },
|
||||||
|
|
@ -85,7 +85,7 @@ export default function MarketingLayout({
|
||||||
<li><a href="/tools/whatsapp-qr-code">WhatsApp QR Code</a></li>
|
<li><a href="/tools/whatsapp-qr-code">WhatsApp QR Code</a></li>
|
||||||
<li><a href="/tools/email-qr-code">Email QR Code</a></li>
|
<li><a href="/tools/email-qr-code">Email QR Code</a></li>
|
||||||
<li><a href="/tools/sms-qr-code">SMS QR Code</a></li>
|
<li><a href="/tools/sms-qr-code">SMS QR Code</a></li>
|
||||||
<li><a href="/tools/phone-qr-code">Phone QR Code</a></li>
|
<li><a href="/tools/call-qr-code-generator">Call QR Code</a></li>
|
||||||
<li><a href="/tools/event-qr-code">Event QR Code</a></li>
|
<li><a href="/tools/event-qr-code">Event QR Code</a></li>
|
||||||
<li><a href="/tools/geolocation-qr-code">Location QR Code</a></li>
|
<li><a href="/tools/geolocation-qr-code">Location QR Code</a></li>
|
||||||
<li><a href="/tools/facebook-qr-code">Facebook QR Code</a></li>
|
<li><a href="/tools/facebook-qr-code">Facebook QR Code</a></li>
|
||||||
|
|
|
||||||
|
|
@ -496,6 +496,9 @@ export default function BulkQRCodeGeneratorPage() {
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{/* How It Works */}
|
{/* How It Works */}
|
||||||
<section className="py-20">
|
<section className="py-20">
|
||||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-6xl">
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-6xl">
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,661 @@
|
||||||
|
import React from 'react';
|
||||||
|
import type { Metadata } from 'next';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import Image from 'next/image';
|
||||||
|
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 } from '@/lib/schema';
|
||||||
|
import {
|
||||||
|
Palette,
|
||||||
|
Upload,
|
||||||
|
Frame,
|
||||||
|
Download,
|
||||||
|
CheckCircle2,
|
||||||
|
Smartphone,
|
||||||
|
FileType,
|
||||||
|
Zap,
|
||||||
|
Shield,
|
||||||
|
Eye
|
||||||
|
} from 'lucide-react';
|
||||||
|
import { MiniGenerator } from '@/components/marketing/MiniGenerator';
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'Custom QR Code Generator with Logo & Colors | QR Master',
|
||||||
|
description: 'Create custom QR codes with your logo, brand colors, and unique frames. Free designer with instant preview. Download PNG/SVG. No signup needed to try.',
|
||||||
|
keywords: [
|
||||||
|
'custom qr code generator',
|
||||||
|
'qr code with logo',
|
||||||
|
'qr code generator with logo',
|
||||||
|
'branded qr code generator',
|
||||||
|
'custom qr code design',
|
||||||
|
'qr code maker with logo',
|
||||||
|
'personalized qr code',
|
||||||
|
'design qr code online'
|
||||||
|
],
|
||||||
|
alternates: {
|
||||||
|
canonical: 'https://www.qrmaster.net/custom-qr-code-generator',
|
||||||
|
languages: {
|
||||||
|
'x-default': 'https://www.qrmaster.net/custom-qr-code-generator',
|
||||||
|
en: 'https://www.qrmaster.net/custom-qr-code-generator',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
openGraph: {
|
||||||
|
title: 'Custom QR Code Generator with Logo & Brand Colors',
|
||||||
|
description: 'Design unique QR codes with your logo, colors, and frames. Free, high-quality exports.',
|
||||||
|
url: 'https://www.qrmaster.net/custom-qr-code-generator',
|
||||||
|
type: 'website',
|
||||||
|
images: [{
|
||||||
|
url: '/images/og/og-custom-qr-generator.png',
|
||||||
|
width: 1200,
|
||||||
|
height: 630
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
twitter: {
|
||||||
|
title: 'Custom QR Code Generator with Logo & Brand Colors',
|
||||||
|
description: 'Design unique QR codes with your logo, colors, and frames. Free, high-quality exports.',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function CustomQRCodeGeneratorPage() {
|
||||||
|
const features = [
|
||||||
|
{
|
||||||
|
icon: Upload,
|
||||||
|
title: 'Logo Integration',
|
||||||
|
description: 'Upload your logo or icon. Auto-resize and safe positioning. Transparent backgrounds supported.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: Palette,
|
||||||
|
title: 'Custom Colors & Gradients',
|
||||||
|
description: 'Match your brand palette. Solid colors or smooth gradients. Separate eye, pattern, frame colors.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: Frame,
|
||||||
|
title: 'Custom Frames',
|
||||||
|
description: '"Scan Me", "Learn More", "Follow Us". 20+ pre-designed frames. Custom text frames.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: FileType,
|
||||||
|
title: 'Multiple Export Formats',
|
||||||
|
description: 'PNG (high-res, up to 4000px). SVG (vector, infinitely scalable). PDF (print-ready).',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: Shield,
|
||||||
|
title: 'Scan-Safe Design Engine',
|
||||||
|
description: 'Automatic error correction (Level H - 30%). Logo placement tested for scannability. Works on all devices.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: Eye,
|
||||||
|
title: 'Instant Preview',
|
||||||
|
description: 'See changes in real-time. Test scan with your phone. What you see is what you get.',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const designExamples = [
|
||||||
|
{
|
||||||
|
name: 'E-Commerce',
|
||||||
|
description: 'Logo center, gradient purple-blue',
|
||||||
|
image: '/images/examples/qr_example_ecommerce_1769163606650.png',
|
||||||
|
category: 'Retail',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Restaurant Menu',
|
||||||
|
description: 'Food icon, warm colors, "Menu" frame',
|
||||||
|
image: '/images/examples/qr_example_restaurant_1769163621640.png',
|
||||||
|
category: 'Hospitality',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Event Ticket',
|
||||||
|
description: 'Gradient, geometric pattern, "Scan to Enter"',
|
||||||
|
image: '/images/examples/qr_example_event_1769163635077.png',
|
||||||
|
category: 'Events',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Business Card',
|
||||||
|
description: 'Minimalist, corporate blue/gray',
|
||||||
|
image: '/images/examples/qr_example_business_1769163647196.png',
|
||||||
|
category: 'Professional',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Social Media',
|
||||||
|
description: 'Instagram-style gradient, "Follow Us"',
|
||||||
|
image: '/images/examples/qr_example_social_1769163660794.png',
|
||||||
|
category: 'Social',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Product Packaging',
|
||||||
|
description: 'Premium black & gold, brand logo',
|
||||||
|
image: '/images/examples/qr_example_packaging_1769163674382.png',
|
||||||
|
category: 'Luxury',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Real Estate',
|
||||||
|
description: 'House icon, professional blue, "View Listing"',
|
||||||
|
image: '/images/examples/qr_example_realestate_1769163689433.png',
|
||||||
|
category: 'Real Estate',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Non-Profit',
|
||||||
|
description: 'Heart icon, warm gradient, "Donate Now"',
|
||||||
|
image: '/images/examples/qr_example_nonprofit_1769163705055.png',
|
||||||
|
category: 'Charity',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const useCases = [
|
||||||
|
{
|
||||||
|
icon: '📢',
|
||||||
|
title: 'Marketing Campaigns',
|
||||||
|
description: 'Print ads, flyers, billboards. Match campaign branding. Track by design/location.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: '💼',
|
||||||
|
title: 'Business Cards',
|
||||||
|
description: 'vCard QR with your logo. Professional first impression. Easy contact sharing.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: '📦',
|
||||||
|
title: 'Product Packaging',
|
||||||
|
description: 'QR codes on labels and boxes. Link to manuals, videos, support. Premium branded look.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: '🎉',
|
||||||
|
title: 'Events & Conferences',
|
||||||
|
description: 'Branded event QR codes. Registration, schedules, networking. Consistent event identity.',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const comparison = [
|
||||||
|
{ feature: 'Colors', generic: 'Black & white only', branded: 'Your brand colors' },
|
||||||
|
{ feature: 'Logo', generic: 'No logo', branded: 'Your logo integrated' },
|
||||||
|
{ feature: 'Design', generic: 'Generic look', branded: 'Professional design' },
|
||||||
|
{ feature: 'Brand Recognition', generic: 'Low', branded: 'Instant brand trust' },
|
||||||
|
{ feature: 'Campaign Tracking', generic: 'Harder to track', branded: 'Campaign-specific branding' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const faqs = [
|
||||||
|
{
|
||||||
|
question: 'Can I add my company logo to a QR code?',
|
||||||
|
answer: 'Yes! Upload your logo (PNG, SVG, JPG) and we\'ll automatically position it safely in the center. The logo is sized to maintain scannability using error correction.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Will my QR code still work with a logo and custom colors?',
|
||||||
|
answer: 'Absolutely. Our generator uses advanced error correction (Level H - 30% redundancy) to ensure your QR code remains scannable even with logos and colors.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'What file formats can I download?',
|
||||||
|
answer: 'High-resolution PNG (up to 4000x4000px), scalable SVG (vector), or print-ready PDF.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Can I use gradients instead of solid colors?',
|
||||||
|
answer: 'Yes! Choose from preset gradients or create custom linear/radial gradients.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'How do I know if my custom QR code works?',
|
||||||
|
answer: 'Use the built-in preview and test scan with your phone camera before downloading.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Is there a limit on logo size?',
|
||||||
|
answer: 'Logos up to 5MB. We automatically resize for optimal scanning. Transparent backgrounds (PNG) work best.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Can I customize the QR code frame?',
|
||||||
|
answer: 'Yes! Choose from 20+ frames ("Scan Me", "Learn More") or create custom text frames.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Are custom QR codes free?',
|
||||||
|
answer: 'Static custom QR codes (URL, text, vCard, WiFi) are completely free forever. Dynamic QR codes (editable, trackable) require a paid plan.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Can I change the corner style?',
|
||||||
|
answer: 'Yes! Customize corner dots, eyes, and patterns. Choose square, rounded, or circular styles.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'What\'s the difference between static and dynamic custom QR codes?',
|
||||||
|
answer: 'Both can be customized with logos/colors. Static = data encoded directly (free, permanent). Dynamic = redirect URL (editable, trackable, requires account).',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const softwareSchema = {
|
||||||
|
'@context': 'https://schema.org',
|
||||||
|
'@type': 'SoftwareApplication',
|
||||||
|
'@id': 'https://www.qrmaster.net/custom-qr-code-generator#software',
|
||||||
|
name: 'QR Master - Custom QR Code Generator with Logo',
|
||||||
|
applicationCategory: 'DesignApplication',
|
||||||
|
offers: {
|
||||||
|
'@type': 'Offer',
|
||||||
|
price: '0',
|
||||||
|
priceCurrency: 'EUR',
|
||||||
|
},
|
||||||
|
featureList: [
|
||||||
|
'Upload custom logo',
|
||||||
|
'Custom brand colors and gradients',
|
||||||
|
'20+ frame designs',
|
||||||
|
'High-resolution PNG downloads',
|
||||||
|
'Scalable SVG exports',
|
||||||
|
'Print-ready PDF output',
|
||||||
|
'Real-time preview',
|
||||||
|
'Scan-safe design validation',
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const howToSchema = {
|
||||||
|
'@context': 'https://schema.org',
|
||||||
|
'@type': 'HowTo',
|
||||||
|
'@id': 'https://www.qrmaster.net/custom-qr-code-generator#howto',
|
||||||
|
name: 'How to Create a Custom QR Code with Logo',
|
||||||
|
step: [
|
||||||
|
{
|
||||||
|
'@type': 'HowToStep',
|
||||||
|
position: 1,
|
||||||
|
name: 'Choose QR Code Type',
|
||||||
|
text: 'Select URL, vCard, WiFi, or other QR code type.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'@type': 'HowToStep',
|
||||||
|
position: 2,
|
||||||
|
name: 'Upload Your Logo',
|
||||||
|
text: 'Upload your company logo (PNG, SVG, JPG). Auto-positioned safely.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'@type': 'HowToStep',
|
||||||
|
position: 3,
|
||||||
|
name: 'Customize Colors & Frame',
|
||||||
|
text: 'Choose brand colors, gradients, and frame style.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'@type': 'HowToStep',
|
||||||
|
position: 4,
|
||||||
|
name: 'Download',
|
||||||
|
text: 'Download as high-res PNG, SVG, or PDF. Ready to print or share.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const faqSchema = {
|
||||||
|
'@context': 'https://schema.org',
|
||||||
|
'@type': 'FAQPage',
|
||||||
|
'@id': 'https://www.qrmaster.net/custom-qr-code-generator#faq',
|
||||||
|
mainEntity: faqs.map((faq) => ({
|
||||||
|
'@type': 'Question',
|
||||||
|
name: faq.question,
|
||||||
|
acceptedAnswer: {
|
||||||
|
'@type': 'Answer',
|
||||||
|
text: faq.answer,
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
|
||||||
|
const breadcrumbItems: BreadcrumbItem[] = [
|
||||||
|
{ name: 'Home', url: '/' },
|
||||||
|
{ name: 'Custom QR Code Generator', url: '/custom-qr-code-generator' },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<SeoJsonLd data={[softwareSchema, howToSchema, faqSchema, breadcrumbSchema(breadcrumbItems)]} />
|
||||||
|
<div className="min-h-screen bg-white">
|
||||||
|
{/* Hero Section */}
|
||||||
|
<section className="relative overflow-hidden bg-gradient-to-br from-purple-50 via-white to-blue-50 py-20">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl">
|
||||||
|
<Breadcrumbs items={breadcrumbItems} />
|
||||||
|
<div className="grid lg:grid-cols-2 gap-12 items-center mt-8">
|
||||||
|
<div className="space-y-8">
|
||||||
|
<div className="inline-flex items-center space-x-2 bg-purple-100 text-purple-800 px-4 py-2 rounded-full text-sm font-semibold">
|
||||||
|
<span>✨</span>
|
||||||
|
<span>Free Static QR Codes Forever</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1 className="text-5xl lg:text-6xl font-bold text-gray-900 leading-tight">
|
||||||
|
Custom QR Code Generator with Logo
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p className="text-xl text-gray-600 leading-relaxed">
|
||||||
|
Add your logo, choose custom colors, and design unique frames. Professional QR codes in minutes – try it free, no signup required.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
{[
|
||||||
|
'No signup required to test',
|
||||||
|
'High-resolution downloads',
|
||||||
|
'Tested for scannability',
|
||||||
|
].map((feature, index) => (
|
||||||
|
<div key={index} className="flex items-center space-x-3">
|
||||||
|
<div className="flex-shrink-0 w-5 h-5 bg-green-500 rounded-full flex items-center justify-center">
|
||||||
|
<CheckCircle2 className="w-3 h-3 text-white" />
|
||||||
|
</div>
|
||||||
|
<span className="text-gray-700">{feature}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col sm:flex-row gap-4">
|
||||||
|
<Link href="/create">
|
||||||
|
<Button size="lg" className="text-lg px-8 py-4 w-full sm:w-auto">
|
||||||
|
Try Designer Now
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="#examples"
|
||||||
|
className="inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 border border-gray-300 text-gray-700 hover:bg-gray-50 focus:ring-gray-500 px-6 py-3 text-lg w-full sm:w-auto"
|
||||||
|
>
|
||||||
|
See Examples
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Preview Card */}
|
||||||
|
<div className="relative">
|
||||||
|
<Card className="p-8 shadow-2xl h-full min-h-[500px]">
|
||||||
|
<MiniGenerator />
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Scan-Safe Technology Section */}
|
||||||
|
<section className="py-16 bg-blue-50">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-5xl">
|
||||||
|
<div className="text-center mb-12">
|
||||||
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
|
Your Logo Won't Break the QR Code – Here's Why
|
||||||
|
</h2>
|
||||||
|
<p className="text-xl text-gray-600 max-w-3xl mx-auto">
|
||||||
|
QR codes have built-in error correction. Our generator uses the highest level (H = 30% redundancy), which means up to 30% of the code can be covered or damaged and still scan perfectly.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Card className="p-8">
|
||||||
|
<div className="prose max-w-none">
|
||||||
|
<p className="text-gray-700 mb-6">
|
||||||
|
When you add a logo, we automatically:
|
||||||
|
</p>
|
||||||
|
<ul className="space-y-3 mb-6">
|
||||||
|
<li className="flex items-start space-x-3">
|
||||||
|
<CheckCircle2 className="w-5 h-5 text-green-500 flex-shrink-0 mt-0.5" />
|
||||||
|
<span>Calculate safe placement zones</span>
|
||||||
|
</li>
|
||||||
|
<li className="flex items-start space-x-3">
|
||||||
|
<CheckCircle2 className="w-5 h-5 text-green-500 flex-shrink-0 mt-0.5" />
|
||||||
|
<span>Size your logo to stay within error correction limits</span>
|
||||||
|
</li>
|
||||||
|
<li className="flex items-start space-x-3">
|
||||||
|
<CheckCircle2 className="w-5 h-5 text-green-500 flex-shrink-0 mt-0.5" />
|
||||||
|
<span>Test scannability before download</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div className="bg-gray-50 border border-gray-200 rounded-lg p-6 mt-6">
|
||||||
|
<p className="text-sm text-gray-600 mb-2 font-semibold">Technical Details:</p>
|
||||||
|
<p className="text-sm text-gray-700">
|
||||||
|
Based on DENSO WAVE QR Code specification (ISO/IEC 18004). Error correction levels: L (7%), M (15%), Q (25%), H (30%). We use Level H for maximum reliability with custom designs.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Features Grid */}
|
||||||
|
<section className="py-20">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl">
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
|
Everything You Need for Branded QR Codes
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||||
|
{features.map((feature, index) => (
|
||||||
|
<Card key={index} className="p-6 hover:shadow-lg transition-shadow">
|
||||||
|
<feature.icon className="w-10 h-10 text-primary-600 mb-4" />
|
||||||
|
<h3 className="text-xl font-semibold text-gray-900 mb-2">
|
||||||
|
{feature.title}
|
||||||
|
</h3>
|
||||||
|
<p className="text-gray-600">{feature.description}</p>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Design Gallery */}
|
||||||
|
<section id="examples" className="py-20 bg-gray-50">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl">
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
|
Get Inspired: Custom QR Code Examples
|
||||||
|
</h2>
|
||||||
|
<p className="text-xl text-gray-600 max-w-3xl mx-auto">
|
||||||
|
Real examples of custom QR codes for different industries and use cases
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||||
|
{designExamples.map((example, index) => (
|
||||||
|
<Card key={index} className="p-4 hover:shadow-xl transition-shadow group">
|
||||||
|
<div className="relative aspect-square mb-4 bg-white rounded-lg overflow-hidden">
|
||||||
|
<Image
|
||||||
|
src={example.image}
|
||||||
|
alt={`${example.name} - ${example.description}`}
|
||||||
|
fill
|
||||||
|
className="object-contain p-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<span className="text-xs font-semibold text-primary-600 uppercase">
|
||||||
|
{example.category}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<h3 className="font-bold text-gray-900">{example.name}</h3>
|
||||||
|
<p className="text-sm text-gray-600">{example.description}</p>
|
||||||
|
<Link href="/create">
|
||||||
|
<Button variant="outline" size="sm" className="w-full mt-3">
|
||||||
|
Use This Style
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* How It Works */}
|
||||||
|
<section className="py-20">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-6xl">
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
|
Create Your Custom QR Code in 4 Steps
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid md:grid-cols-2 gap-8">
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
step: 1,
|
||||||
|
title: 'Choose QR Type & Enter Data',
|
||||||
|
description: 'URL, vCard, WiFi, Text, Email, SMS. Enter your destination.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
step: 2,
|
||||||
|
title: 'Upload Your Logo',
|
||||||
|
description: 'Drag & drop PNG/SVG/JPG. Auto-positioned and sized. Or choose from icon library.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
step: 3,
|
||||||
|
title: 'Customize Design',
|
||||||
|
description: 'Pick brand colors or gradients. Choose frame style ("Scan Me", custom text). Adjust corner shapes.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
step: 4,
|
||||||
|
title: 'Download & Use',
|
||||||
|
description: 'High-res PNG or vector SVG. Print-ready quality. Scan-tested and verified.',
|
||||||
|
},
|
||||||
|
].map((step, index) => (
|
||||||
|
<Card key={index} className="p-6">
|
||||||
|
<div className="flex items-start space-x-4">
|
||||||
|
<div className="flex-shrink-0 w-12 h-12 bg-primary-100 rounded-full flex items-center justify-center">
|
||||||
|
<span className="text-xl font-bold text-primary-600">{step.step}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex-1">
|
||||||
|
<h3 className="text-xl font-bold text-gray-900 mb-2">{step.title}</h3>
|
||||||
|
<p className="text-gray-600">{step.description}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Comparison Section */}
|
||||||
|
<section className="py-20 bg-gray-50">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-5xl">
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
|
Why Custom QR Codes Perform Better
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Card className="overflow-hidden">
|
||||||
|
<table className="w-full">
|
||||||
|
<thead className="bg-gray-100">
|
||||||
|
<tr>
|
||||||
|
<th className="px-6 py-4 text-left text-gray-900 font-semibold">Feature</th>
|
||||||
|
<th className="px-6 py-4 text-center text-gray-900 font-semibold">Generic QR Code</th>
|
||||||
|
<th className="px-6 py-4 text-center text-primary-600 font-semibold">Custom Branded QR Code</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="divide-y divide-gray-200">
|
||||||
|
{comparison.map((row, index) => (
|
||||||
|
<tr key={index}>
|
||||||
|
<td className="px-6 py-4 text-gray-900 font-medium">{row.feature}</td>
|
||||||
|
<td className="px-6 py-4 text-center text-gray-600">❌ {row.generic}</td>
|
||||||
|
<td className="px-6 py-4 text-center text-primary-600 font-semibold">✅ {row.branded}</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<div className="mt-8 bg-blue-50 border border-blue-200 rounded-lg p-6">
|
||||||
|
<p className="text-sm text-gray-700">
|
||||||
|
<strong>Note:</strong> Branded QR codes can improve brand recognition and recall, user trust and engagement, and campaign tracking and attribution.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Use Cases */}
|
||||||
|
<section className="py-20">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl">
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
|
Perfect For Every Industry
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-8">
|
||||||
|
{useCases.map((useCase, index) => (
|
||||||
|
<Card key={index} className="p-6 text-center hover:shadow-lg transition-shadow">
|
||||||
|
<div className="text-5xl mb-4">{useCase.icon}</div>
|
||||||
|
<h3 className="text-xl font-semibold text-gray-900 mb-3">{useCase.title}</h3>
|
||||||
|
<p className="text-gray-600">{useCase.description}</p>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* FAQ Section */}
|
||||||
|
<section className="py-20 bg-gray-50">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-4xl">
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
|
Frequently Asked Questions
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-6">
|
||||||
|
{faqs.map((faq, index) => (
|
||||||
|
<Card key={index} className="p-6">
|
||||||
|
<h3 className="text-lg font-semibold text-gray-900 mb-3">
|
||||||
|
{faq.question}
|
||||||
|
</h3>
|
||||||
|
<p className="text-gray-600">{faq.answer}</p>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Trust Section */}
|
||||||
|
<section className="py-16">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-5xl">
|
||||||
|
<div className="text-center">
|
||||||
|
<h2 className="text-3xl font-bold text-gray-900 mb-8">
|
||||||
|
Secure and Reliable
|
||||||
|
</h2>
|
||||||
|
<div className="flex flex-wrap justify-center gap-8">
|
||||||
|
<div className="flex items-center space-x-2 text-gray-700">
|
||||||
|
<div className="w-8 h-8 bg-green-100 rounded-full flex items-center justify-center">
|
||||||
|
<CheckCircle2 className="w-5 h-5 text-green-600" />
|
||||||
|
</div>
|
||||||
|
<span>Your data is never stored</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center space-x-2 text-gray-700">
|
||||||
|
<div className="w-8 h-8 bg-green-100 rounded-full flex items-center justify-center">
|
||||||
|
<CheckCircle2 className="w-5 h-5 text-green-600" />
|
||||||
|
</div>
|
||||||
|
<span>Works on all modern devices and QR scanners</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center space-x-2 text-gray-700">
|
||||||
|
<div className="w-8 h-8 bg-green-100 rounded-full flex items-center justify-center">
|
||||||
|
<CheckCircle2 className="w-5 h-5 text-green-600" />
|
||||||
|
</div>
|
||||||
|
<span>Used by businesses and creators worldwide</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Final CTA */}
|
||||||
|
<section className="py-20 bg-gradient-to-r from-purple-600 to-blue-600 text-white">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-4xl text-center">
|
||||||
|
<h2 className="text-4xl font-bold mb-6">
|
||||||
|
Start Creating Branded QR Codes Today
|
||||||
|
</h2>
|
||||||
|
<p className="text-xl mb-8 text-purple-100">
|
||||||
|
Free static QR codes with logo, colors, and frames. No signup required to try. Upgrade for tracking and bulk generation.
|
||||||
|
</p>
|
||||||
|
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||||
|
<Link href="/create">
|
||||||
|
<Button
|
||||||
|
size="lg"
|
||||||
|
variant="secondary"
|
||||||
|
className="text-lg px-8 py-4 w-full sm:w-auto bg-white text-purple-600 hover:bg-gray-100"
|
||||||
|
>
|
||||||
|
Try Designer Free
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
<Link href="/pricing">
|
||||||
|
<Button
|
||||||
|
size="lg"
|
||||||
|
variant="outline"
|
||||||
|
className="text-lg px-8 py-4 w-full sm:w-auto border-white text-white hover:bg-white/10"
|
||||||
|
>
|
||||||
|
See Pricing for Dynamic Codes
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,740 @@
|
||||||
|
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 } from '@/lib/schema';
|
||||||
|
import {
|
||||||
|
LayoutDashboard,
|
||||||
|
FolderTree,
|
||||||
|
Edit3,
|
||||||
|
Users,
|
||||||
|
BarChart3,
|
||||||
|
Bell,
|
||||||
|
CheckCircle2,
|
||||||
|
XCircle,
|
||||||
|
Store,
|
||||||
|
UtensilsCrossed,
|
||||||
|
CalendarDays,
|
||||||
|
Megaphone,
|
||||||
|
} from 'lucide-react';
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'QR Code Management Software – Organize, Edit & Scale | QR Master',
|
||||||
|
description: 'Manage QR codes at scale with folders, bulk editing, team collaboration, and campaign organization. Centralized dashboard for businesses. Free trial available.',
|
||||||
|
keywords: [
|
||||||
|
'manage qr codes',
|
||||||
|
'qr code management software',
|
||||||
|
'qr code management system',
|
||||||
|
'bulk qr code management',
|
||||||
|
'qr code campaign management',
|
||||||
|
'qr code dashboard',
|
||||||
|
'organize qr codes',
|
||||||
|
],
|
||||||
|
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: 'QR Code Management Software – Organize, Edit & Scale',
|
||||||
|
description: 'Manage QR codes at scale with folders, bulk editing, team collaboration, and campaign organization.',
|
||||||
|
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: 'QR Code Management Software – Organize, Edit & Scale',
|
||||||
|
description: 'Manage QR codes at scale with folders, bulk editing, team collaboration, and campaign organization.',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ManageQRCodesPage() {
|
||||||
|
const problems = [
|
||||||
|
{
|
||||||
|
icon: BarChart3,
|
||||||
|
title: 'No Visibility',
|
||||||
|
issues: [
|
||||||
|
'Can\'t find QR codes across campaigns',
|
||||||
|
'No central place to see all codes',
|
||||||
|
'Hard to track which ones are active',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: Edit3,
|
||||||
|
title: 'Can\'t Update or Organize',
|
||||||
|
issues: [
|
||||||
|
'Printed QR codes are permanent (static)',
|
||||||
|
'No way to organize by campaign/location',
|
||||||
|
'Manual spreadsheet tracking',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: Users,
|
||||||
|
title: 'No Team Collaboration',
|
||||||
|
issues: [
|
||||||
|
'QR codes scattered across devices',
|
||||||
|
'No centralized management system',
|
||||||
|
'No permissions or access control',
|
||||||
|
'Can\'t track who created/edited what',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const features = [
|
||||||
|
{
|
||||||
|
icon: LayoutDashboard,
|
||||||
|
title: 'Centralized Dashboard',
|
||||||
|
description: 'All QR codes in one place. Search, filter, sort by campaign/date/type. Quick performance overview.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: FolderTree,
|
||||||
|
title: 'Campaign Organization',
|
||||||
|
description: 'Create folders and tags. Group by location, product, event. Archive old campaigns.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: Edit3,
|
||||||
|
title: 'Bulk Editing',
|
||||||
|
description: 'Edit multiple QR destinations at once. Bulk export, duplicate, archive. Schedule URL changes in advance.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: Users,
|
||||||
|
title: 'Team Collaboration',
|
||||||
|
description: 'Invite team members. Set roles (viewer, editor, admin). Activity log for accountability.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: BarChart3,
|
||||||
|
title: 'Performance Tracking',
|
||||||
|
description: 'Track scans per QR code. See locations, devices, timestamps. Export analytics to CSV.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: Bell,
|
||||||
|
title: 'Smart Alerts',
|
||||||
|
description: 'Get notified on high scan activity. Alert when errors occur. Weekly performance summaries.',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const useCases = [
|
||||||
|
{
|
||||||
|
icon: Store,
|
||||||
|
title: 'Retail & E-Commerce',
|
||||||
|
description: 'Manage product QR codes across locations. Track in-store vs online performance. Update promo URLs seasonally.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: UtensilsCrossed,
|
||||||
|
title: 'Restaurants & Hospitality',
|
||||||
|
description: 'Manage digital menu QR codes. Update locations/specials easily. Track table/location-specific scans.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: CalendarDays,
|
||||||
|
title: 'Events & Conferences',
|
||||||
|
description: 'Manage attendee/session QR codes. Track check-ins in real-time. Organize by event, date, venue.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: Megaphone,
|
||||||
|
title: 'Marketing Agencies',
|
||||||
|
description: 'Manage multiple client campaigns. Team permissions and white-label reports. Client-specific analytics.',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const comparison = [
|
||||||
|
{ feature: 'Create QR Codes', free: 'Static only', qrMaster: 'Static + Dynamic' },
|
||||||
|
{ feature: 'Central Dashboard', free: false, qrMaster: true },
|
||||||
|
{ feature: 'Edit After Deploy', free: false, qrMaster: true },
|
||||||
|
{ feature: 'Organize Campaigns', free: false, qrMaster: true },
|
||||||
|
{ feature: 'Team Collaboration', free: false, qrMaster: true },
|
||||||
|
{ feature: 'Bulk Operations', free: false, qrMaster: true },
|
||||||
|
{ feature: 'Analytics', free: false, qrMaster: true },
|
||||||
|
{ feature: 'API Access', free: false, qrMaster: true },
|
||||||
|
];
|
||||||
|
|
||||||
|
const plans = [
|
||||||
|
{
|
||||||
|
name: 'Free',
|
||||||
|
price: '€0',
|
||||||
|
period: 'forever',
|
||||||
|
features: [
|
||||||
|
'3 Dynamic QR Codes',
|
||||||
|
'Basic Dashboard',
|
||||||
|
'Basic Analytics',
|
||||||
|
'Perfect for trying',
|
||||||
|
],
|
||||||
|
cta: 'Start Free',
|
||||||
|
href: '/signup',
|
||||||
|
highlighted: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Pro',
|
||||||
|
price: '€9',
|
||||||
|
period: 'per month',
|
||||||
|
features: [
|
||||||
|
'50 Dynamic QR Codes',
|
||||||
|
'Advanced Analytics',
|
||||||
|
'Team Collaboration (3 users)',
|
||||||
|
'Priority Support',
|
||||||
|
],
|
||||||
|
cta: 'Start Free Trial',
|
||||||
|
href: '/signup?plan=pro',
|
||||||
|
highlighted: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Business',
|
||||||
|
price: '€29',
|
||||||
|
period: 'per month',
|
||||||
|
features: [
|
||||||
|
'500 Dynamic QR Codes',
|
||||||
|
'Full Analytics + CSV Export',
|
||||||
|
'Unlimited Team Members',
|
||||||
|
'API Access',
|
||||||
|
],
|
||||||
|
cta: 'Start Free Trial',
|
||||||
|
href: '/signup?plan=business',
|
||||||
|
highlighted: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const faqs = [
|
||||||
|
{
|
||||||
|
question: 'What does "manage QR codes" mean?',
|
||||||
|
answer: 'QR code management means having a central dashboard to create, organize, edit, track, and analyze all your QR codes in one place instead of scattered files.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Can I edit a QR code after printing it?',
|
||||||
|
answer: 'Yes, with dynamic QR codes. QR Master uses a redirect URL, so you can change the destination anytime. The printed QR code image stays the same.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'How many QR codes can I manage?',
|
||||||
|
answer: 'Pro plan: 50 dynamic QR codes. Business plan: 500. Enterprise: Unlimited. All plans include unlimited static QR codes.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Can my team access and edit QR codes?',
|
||||||
|
answer: 'Yes! Invite team members on Business and Enterprise plans. Set permissions (viewer, editor, admin) for each member.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'What analytics can I track?',
|
||||||
|
answer: 'Total scans, unique scans, locations (city/country), devices (iOS/Android), browsers, timestamps, referrers. Export to CSV.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Can I organize QR codes by campaign?',
|
||||||
|
answer: 'Absolutely. Use folders, tags, and custom labels to organize by campaign, location, product, or any criteria.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'What happens to my dynamic QR codes if I cancel?',
|
||||||
|
answer: 'Dynamic QR codes require an active subscription to redirect. Check our terms for data retention policies. You can always export your data and download static versions.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Is there an API for bulk management?',
|
||||||
|
answer: 'Yes, Business and Enterprise plans include full API access for creating, editing, and tracking QR codes programmatically.',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const softwareSchema = {
|
||||||
|
'@context': 'https://schema.org',
|
||||||
|
'@type': 'SoftwareApplication',
|
||||||
|
'@id': 'https://www.qrmaster.net/manage-qr-codes#software',
|
||||||
|
name: 'QR Master - QR Code Management Platform',
|
||||||
|
applicationCategory: 'BusinessApplication',
|
||||||
|
offers: {
|
||||||
|
'@type': 'AggregateOffer',
|
||||||
|
lowPrice: '0',
|
||||||
|
highPrice: '29',
|
||||||
|
priceCurrency: 'EUR',
|
||||||
|
},
|
||||||
|
featureList: [
|
||||||
|
'Centralized QR code dashboard',
|
||||||
|
'Campaign organization with folders and tags',
|
||||||
|
'Bulk editing and operations',
|
||||||
|
'Team collaboration with permissions',
|
||||||
|
'Real-time scan analytics',
|
||||||
|
'API access for automation',
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const breadcrumbItems: BreadcrumbItem[] = [
|
||||||
|
{ name: 'Home', url: '/' },
|
||||||
|
{ name: 'Manage QR Codes', url: '/manage-qr-codes' },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<SeoJsonLd data={[softwareSchema, breadcrumbSchema(breadcrumbItems)]} />
|
||||||
|
<div className="min-h-screen bg-white">
|
||||||
|
{/* Hero Section */}
|
||||||
|
<section className="relative overflow-hidden bg-gradient-to-br from-green-50 via-white to-blue-50 py-20">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl">
|
||||||
|
<Breadcrumbs items={breadcrumbItems} />
|
||||||
|
<div className="grid lg:grid-cols-2 gap-12 items-center mt-8">
|
||||||
|
<div className="space-y-8">
|
||||||
|
<div className="inline-flex items-center space-x-2 bg-green-100 text-green-800 px-4 py-2 rounded-full text-sm font-semibold">
|
||||||
|
<span>✅</span>
|
||||||
|
<span>Get Started Free</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1 className="text-5xl lg:text-6xl font-bold text-gray-900 leading-tight">
|
||||||
|
QR Code Management Software – Organize, Edit & Scale
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p className="text-xl text-gray-600 leading-relaxed">
|
||||||
|
The complete QR code management platform for businesses. Organize campaigns, edit in bulk, collaborate with teams, and track performance from one central dashboard.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
{[
|
||||||
|
'No Credit Card Required',
|
||||||
|
'Full Features',
|
||||||
|
'Cancel Anytime',
|
||||||
|
].map((feature, index) => (
|
||||||
|
<div key={index} className="flex items-center space-x-3">
|
||||||
|
<div className="flex-shrink-0 w-5 h-5 bg-green-500 rounded-full flex items-center justify-center">
|
||||||
|
<CheckCircle2 className="w-3 h-3 text-white" />
|
||||||
|
</div>
|
||||||
|
<span className="text-gray-700">{feature}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col sm:flex-row gap-4">
|
||||||
|
<Link href="/signup">
|
||||||
|
<Button size="lg" className="text-lg px-8 py-4 w-full sm:w-auto">
|
||||||
|
Get Started Free
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="#dashboard-preview"
|
||||||
|
className="inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 border border-gray-300 text-gray-700 hover:bg-gray-50 focus:ring-gray-500 px-6 py-3 text-lg w-full sm:w-auto"
|
||||||
|
>
|
||||||
|
See Dashboard Demo
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Dashboard Preview Card */}
|
||||||
|
<div className="relative">
|
||||||
|
<Card className="p-6 shadow-2xl">
|
||||||
|
<h3 className="font-semibold text-lg mb-4">Dashboard Overview</h3>
|
||||||
|
<div className="space-y-3">
|
||||||
|
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
|
||||||
|
<div className="flex items-center justify-between mb-2">
|
||||||
|
<span className="text-sm font-semibold text-gray-700">All QR Codes</span>
|
||||||
|
<span className="text-2xl font-bold text-blue-600">127</span>
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-gray-600">Across 12 campaigns</div>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-2 gap-3">
|
||||||
|
<div className="bg-green-50 border border-green-200 rounded-lg p-3">
|
||||||
|
<div className="text-xs text-gray-600 mb-1">Active</div>
|
||||||
|
<div className="text-xl font-bold text-green-600">94</div>
|
||||||
|
</div>
|
||||||
|
<div className="bg-gray-100 border border-gray-200 rounded-lg p-3">
|
||||||
|
<div className="text-xs text-gray-600 mb-1">Archived</div>
|
||||||
|
<div className="text-xl font-bold text-gray-600">33</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="bg-purple-50 border border-purple-200 rounded-lg p-3">
|
||||||
|
<div className="text-xs text-gray-600 mb-2">Recent Activity</div>
|
||||||
|
<div className="space-y-1 text-xs">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<span className="text-gray-700">Campaign "Summer Sale" edited</span>
|
||||||
|
<span className="text-gray-500">2m ago</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<span className="text-gray-700">Bulk update: 12 codes</span>
|
||||||
|
<span className="text-gray-500">1h ago</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4 pt-4 border-t border-gray-200">
|
||||||
|
<div className="flex items-center justify-between text-sm">
|
||||||
|
<span className="text-gray-600">Team Members</span>
|
||||||
|
<div className="flex -space-x-2">
|
||||||
|
{[1, 2, 3].map((i) => (
|
||||||
|
<div key={i} className="w-8 h-8 rounded-full bg-gradient-to-br from-blue-400 to-purple-500 border-2 border-white" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Problem Statement */}
|
||||||
|
<section className="py-20 bg-gray-50">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl">
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
|
Why Managing QR Codes Manually is Chaos
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid md:grid-cols-3 gap-8">
|
||||||
|
{problems.map((problem, index) => (
|
||||||
|
<Card key={index} className="p-6">
|
||||||
|
<problem.icon className="w-12 h-12 text-red-600 mb-4" />
|
||||||
|
<h3 className="text-xl font-bold text-gray-900 mb-4">{problem.title}</h3>
|
||||||
|
<ul className="space-y-2">
|
||||||
|
{problem.issues.map((issue, idx) => (
|
||||||
|
<li key={idx} className="flex items-start space-x-2">
|
||||||
|
<XCircle className="w-5 h-5 text-red-500 flex-shrink-0 mt-0.5" />
|
||||||
|
<span className="text-gray-600">{issue}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="text-center mt-12">
|
||||||
|
<p className="text-2xl font-semibold text-gray-700">
|
||||||
|
A Complete Management Platform Solves All of This ↓
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Core Features */}
|
||||||
|
<section className="py-20">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl">
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
|
Everything You Need to Manage QR Codes at Scale
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||||
|
{features.map((feature, index) => (
|
||||||
|
<Card key={index} className="p-6 hover:shadow-lg transition-shadow">
|
||||||
|
<feature.icon className="w-10 h-10 text-primary-600 mb-4" />
|
||||||
|
<h3 className="text-xl font-semibold text-gray-900 mb-2">
|
||||||
|
{feature.title}
|
||||||
|
</h3>
|
||||||
|
<p className="text-gray-600">{feature.description}</p>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Workflow Diagram */}
|
||||||
|
<section className="py-20 bg-blue-50">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-6xl">
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
|
Your QR Code Management Workflow
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-6">
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
step: 1,
|
||||||
|
title: 'Create & Customize',
|
||||||
|
description: 'Upload CSV or create individually',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
step: 2,
|
||||||
|
title: 'Organize',
|
||||||
|
description: 'Tag, folder, assign to campaigns',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
step: 3,
|
||||||
|
title: 'Deploy',
|
||||||
|
description: 'Download, print, distribute',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
step: 4,
|
||||||
|
title: 'Track & Analyze',
|
||||||
|
description: 'Monitor scans, locations, devices',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
step: 5,
|
||||||
|
title: 'Optimize',
|
||||||
|
description: 'Edit URLs, A/B test, improve',
|
||||||
|
},
|
||||||
|
].map((step, index) => (
|
||||||
|
<div key={index}>
|
||||||
|
<Card className="p-6">
|
||||||
|
<div className="flex items-center space-x-4">
|
||||||
|
<div className="flex-shrink-0 w-12 h-12 bg-primary-600 text-white rounded-full flex items-center justify-center text-xl font-bold">
|
||||||
|
{step.step}
|
||||||
|
</div>
|
||||||
|
<div className="flex-1">
|
||||||
|
<h3 className="text-xl font-bold text-gray-900">{step.title}</h3>
|
||||||
|
<p className="text-gray-600">{step.description}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
{index < 4 && (
|
||||||
|
<div className="flex justify-center my-2">
|
||||||
|
<div className="w-1 h-8 bg-primary-300" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Dashboard Preview */}
|
||||||
|
<section id="dashboard-preview" className="py-20">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-6xl">
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
|
See Your Dashboard in Action
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Card className="p-8 bg-gradient-to-br from-gray-50 to-white">
|
||||||
|
<div className="space-y-6">
|
||||||
|
<div className="flex items-center justify-between pb-4 border-b border-gray-200">
|
||||||
|
<h3 className="text-xl font-bold">QR Code Management</h3>
|
||||||
|
<Link href="/signup">
|
||||||
|
<Button size="sm">Sign Up</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid gap-4">
|
||||||
|
{[
|
||||||
|
{ name: 'Summer Campaign 2024', scans: 1247, status: 'Active', folder: 'Marketing' },
|
||||||
|
{ name: 'Product Launch - Widget Pro', scans: 892, status: 'Active', folder: 'Products' },
|
||||||
|
{ name: 'Event Check-in - TechConf', scans: 2341, status: 'Complete', folder: 'Events' },
|
||||||
|
].map((qr, index) => (
|
||||||
|
<div key={index} className="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg hover:shadow-md transition-shadow">
|
||||||
|
<div className="flex-1">
|
||||||
|
<div className="font-semibold text-gray-900">{qr.name}</div>
|
||||||
|
<div className="text-sm text-gray-500">📁 {qr.folder}</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center space-x-6">
|
||||||
|
<div className="text-center">
|
||||||
|
<div className="text-2xl font-bold text-primary-600">{qr.scans.toLocaleString()}</div>
|
||||||
|
<div className="text-xs text-gray-500">scans</div>
|
||||||
|
</div>
|
||||||
|
<div className={`px-3 py-1 rounded-full text-xs font-semibold ${qr.status === 'Active'
|
||||||
|
? 'bg-green-100 text-green-800'
|
||||||
|
: 'bg-gray-100 text-gray-600'
|
||||||
|
}`}>
|
||||||
|
{qr.status}
|
||||||
|
</div>
|
||||||
|
<Button variant="ghost" size="sm">
|
||||||
|
<Edit3 className="w-4 h-4" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center justify-center space-x-8 pt-6 border-t border-gray-200 text-sm text-gray-600">
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<CheckCircle2 className="w-4 h-4 text-green-500" />
|
||||||
|
<span>View all codes at a glance</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<CheckCircle2 className="w-4 h-4 text-green-500" />
|
||||||
|
<span>Click to edit destination instantly</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<CheckCircle2 className="w-4 h-4 text-green-500" />
|
||||||
|
<span>Filter by campaign or folder</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Use Cases by Industry */}
|
||||||
|
<section className="py-20 bg-gray-50">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl">
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
|
QR Code Management for Every Business
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid md:grid-cols-2 gap-8">
|
||||||
|
{useCases.map((useCase, index) => (
|
||||||
|
<Card key={index} className="p-8">
|
||||||
|
<useCase.icon className="w-12 h-12 text-primary-600 mb-4" />
|
||||||
|
<h3 className="text-2xl font-bold text-gray-900 mb-3">{useCase.title}</h3>
|
||||||
|
<p className="text-gray-600">{useCase.description}</p>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Feature Comparison */}
|
||||||
|
<section className="py-20">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-5xl">
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
|
Free QR Tools vs QR Code Management Platform
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Card className="overflow-hidden">
|
||||||
|
<table className="w-full">
|
||||||
|
<thead className="bg-gray-100">
|
||||||
|
<tr>
|
||||||
|
<th className="px-6 py-4 text-left text-gray-900 font-semibold">Feature</th>
|
||||||
|
<th className="px-6 py-4 text-center text-gray-900 font-semibold">Free QR Tool</th>
|
||||||
|
<th className="px-6 py-4 text-center text-primary-600 font-semibold">QR Master Manage</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="divide-y divide-gray-200">
|
||||||
|
{comparison.map((row, index) => (
|
||||||
|
<tr key={index}>
|
||||||
|
<td className="px-6 py-4 text-gray-900 font-medium">{row.feature}</td>
|
||||||
|
<td className="px-6 py-4 text-center">
|
||||||
|
{typeof row.free === 'boolean' ? (
|
||||||
|
row.free ? (
|
||||||
|
<span className="text-green-500 text-2xl">✓</span>
|
||||||
|
) : (
|
||||||
|
<span className="text-red-500 text-2xl">✗</span>
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<span className="text-gray-600">{row.free}</span>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td className="px-6 py-4 text-center">
|
||||||
|
{typeof row.qrMaster === 'boolean' ? (
|
||||||
|
<span className="text-green-500 text-2xl">✓</span>
|
||||||
|
) : (
|
||||||
|
<span className="text-primary-600 font-semibold">{row.qrMaster}</span>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* FAQ Section */}
|
||||||
|
<section className="py-20 bg-gray-50">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-4xl">
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
|
Frequently Asked Questions
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-6">
|
||||||
|
{faqs.map((faq, index) => (
|
||||||
|
<Card key={index} className="p-6">
|
||||||
|
<h3 className="text-lg font-semibold text-gray-900 mb-3">
|
||||||
|
{faq.question}
|
||||||
|
</h3>
|
||||||
|
<p className="text-gray-600">{faq.answer}</p>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Pricing Teaser */}
|
||||||
|
<section className="py-20">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl">
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
|
Start Managing Your QR Codes Today
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid md:grid-cols-3 gap-8">
|
||||||
|
{plans.map((plan, index) => (
|
||||||
|
<Card
|
||||||
|
key={index}
|
||||||
|
className={`p-8 ${plan.highlighted
|
||||||
|
? 'border-2 border-primary-600 shadow-xl relative'
|
||||||
|
: ''
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{plan.highlighted && (
|
||||||
|
<div className="absolute -top-4 left-1/2 transform -translate-x-1/2 bg-primary-600 text-white px-4 py-1 rounded-full text-sm font-semibold">
|
||||||
|
Most Popular
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="text-center mb-6">
|
||||||
|
<h3 className="text-2xl font-bold text-gray-900 mb-2">{plan.name}</h3>
|
||||||
|
<div className="flex items-baseline justify-center">
|
||||||
|
<span className="text-4xl font-bold text-gray-900">{plan.price}</span>
|
||||||
|
<span className="text-gray-600 ml-2">/{plan.period}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul className="space-y-3 mb-8">
|
||||||
|
{plan.features.map((feature, idx) => (
|
||||||
|
<li key={idx} className="flex items-start space-x-3">
|
||||||
|
<CheckCircle2 className="w-5 h-5 text-green-500 flex-shrink-0 mt-0.5" />
|
||||||
|
<span className="text-gray-600">{feature}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<Link href={plan.href}>
|
||||||
|
<Button
|
||||||
|
size="lg"
|
||||||
|
variant={plan.highlighted ? undefined : 'outline'}
|
||||||
|
className="w-full"
|
||||||
|
>
|
||||||
|
{plan.cta}
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="text-center mt-8 text-sm text-gray-600">
|
||||||
|
No credit card required • Full features • Cancel anytime
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Trust & CTA */}
|
||||||
|
<section className="py-20 bg-gradient-to-r from-green-600 to-blue-600 text-white">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-5xl text-center">
|
||||||
|
<h2 className="text-4xl font-bold mb-6">
|
||||||
|
Built for Teams and Businesses
|
||||||
|
</h2>
|
||||||
|
<p className="text-xl mb-8 text-green-100">
|
||||||
|
QR Master helps marketing teams, agencies, event organizers, and businesses manage their QR codes efficiently.
|
||||||
|
</p>
|
||||||
|
<div className="flex flex-wrap justify-center gap-8 mb-8">
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<CheckCircle2 className="w-6 h-6" />
|
||||||
|
<span>Built for retail, events, hospitality, and more</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<CheckCircle2 className="w-6 h-6" />
|
||||||
|
<span>Secure data handling</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<CheckCircle2 className="w-6 h-6" />
|
||||||
|
<span>Reliable uptime and performance</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Link href="/signup">
|
||||||
|
<Button
|
||||||
|
size="lg"
|
||||||
|
variant="secondary"
|
||||||
|
className="text-lg px-8 py-4 bg-white text-green-600 hover:bg-gray-100"
|
||||||
|
>
|
||||||
|
Start Free Trial
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -21,6 +21,7 @@ export async function generateMetadata(): Promise<Metadata> {
|
||||||
return {
|
return {
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
|
keywords: ['qr generator', 'free qr code generator', 'custom qr code generator', 'qr code maker', 'online qr code generator', 'dynamic qr code', 'qr code with logo'],
|
||||||
alternates: {
|
alternates: {
|
||||||
canonical: 'https://www.qrmaster.net/',
|
canonical: 'https://www.qrmaster.net/',
|
||||||
languages: {
|
languages: {
|
||||||
|
|
@ -60,7 +61,7 @@ export default function HomePage() {
|
||||||
vCard QR codes for digital business cards, and restaurant menu QR codes.
|
vCard QR codes for digital business cards, and restaurant menu QR codes.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Start free with 3 dynamic QR codes and unlimited static codes. Upgrade to Pro for 50 codes
|
Start free with 3 active dynamic QR codes and unlimited static codes. Upgrade to Pro for 50 codes
|
||||||
with advanced analytics, or Business for 500 codes with bulk creation and priority support.
|
with advanced analytics, or Business for 500 codes with bulk creation and priority support.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ export default function PricingPage() {
|
||||||
period: 'forever',
|
period: 'forever',
|
||||||
showDiscount: false,
|
showDiscount: false,
|
||||||
features: [
|
features: [
|
||||||
'3 dynamic QR codes',
|
'3 active dynamic QR codes (8 types available)',
|
||||||
'Unlimited static QR codes',
|
'Unlimited static QR codes',
|
||||||
'Basic scan tracking',
|
'Basic scan tracking',
|
||||||
'Standard QR design templates',
|
'Standard QR design templates',
|
||||||
|
|
|
||||||
|
|
@ -319,79 +319,79 @@ export default function QRCodeTrackingPage() {
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Comparison Table */}
|
{/* Comparison Table */}
|
||||||
<section className="py-20 bg-gray-50">
|
<section className="py-20 bg-gray-50">
|
||||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-5xl">
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-5xl">
|
||||||
<div className="text-center mb-16">
|
<div className="text-center mb-16">
|
||||||
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||||
QR Master vs Free Tools
|
QR Master vs Free Tools
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-xl text-gray-600">
|
<p className="text-xl text-gray-600">
|
||||||
See why businesses choose QR Master for QR code tracking
|
See why businesses choose QR Master for QR code tracking
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Card className="overflow-hidden">
|
<Card className="overflow-hidden">
|
||||||
<table className="w-full">
|
<table className="w-full">
|
||||||
<thead className="bg-gray-100">
|
<thead className="bg-gray-100">
|
||||||
<tr>
|
<tr>
|
||||||
<th className="px-6 py-4 text-left text-gray-900 font-semibold">Feature</th>
|
<th className="px-6 py-4 text-left text-gray-900 font-semibold">Feature</th>
|
||||||
<th className="px-6 py-4 text-center text-gray-900 font-semibold">Free Tools</th>
|
<th className="px-6 py-4 text-center text-gray-900 font-semibold">Free Tools</th>
|
||||||
<th className="px-6 py-4 text-center text-primary-600 font-semibold">QR Master</th>
|
<th className="px-6 py-4 text-center text-primary-600 font-semibold">QR Master</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-gray-200">
|
<tbody className="divide-y divide-gray-200">
|
||||||
{comparisonData.map((row, index) => (
|
{comparisonData.map((row, index) => (
|
||||||
<tr key={index}>
|
<tr key={index}>
|
||||||
<td className="px-6 py-4 text-gray-900 font-medium">{row.feature}</td>
|
<td className="px-6 py-4 text-gray-900 font-medium">{row.feature}</td>
|
||||||
<td className="px-6 py-4 text-center">
|
<td className="px-6 py-4 text-center">
|
||||||
{typeof row.free === 'boolean' ? (
|
{typeof row.free === 'boolean' ? (
|
||||||
row.free ? (
|
row.free ? (
|
||||||
|
<span className="text-green-500 text-2xl">✓</span>
|
||||||
|
) : (
|
||||||
|
<span className="text-red-500 text-2xl">✗</span>
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<span className="text-gray-600">{row.free}</span>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td className="px-6 py-4 text-center">
|
||||||
|
{typeof row.qrMaster === 'boolean' ? (
|
||||||
<span className="text-green-500 text-2xl">✓</span>
|
<span className="text-green-500 text-2xl">✓</span>
|
||||||
) : (
|
) : (
|
||||||
<span className="text-red-500 text-2xl">✗</span>
|
<span className="text-primary-600 font-semibold">{row.qrMaster}</span>
|
||||||
)
|
)}
|
||||||
) : (
|
</td>
|
||||||
<span className="text-gray-600">{row.free}</span>
|
</tr>
|
||||||
)}
|
))}
|
||||||
</td>
|
</tbody>
|
||||||
<td className="px-6 py-4 text-center">
|
</table>
|
||||||
{typeof row.qrMaster === 'boolean' ? (
|
</Card>
|
||||||
<span className="text-green-500 text-2xl">✓</span>
|
|
||||||
) : (
|
|
||||||
<span className="text-primary-600 font-semibold">{row.qrMaster}</span>
|
|
||||||
)}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* CTA Section */}
|
|
||||||
<section className="py-20 bg-gradient-to-r from-primary-600 to-purple-600 text-white">
|
|
||||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-4xl text-center">
|
|
||||||
<h2 className="text-4xl font-bold mb-6">
|
|
||||||
Start Tracking Your QR Codes Today
|
|
||||||
</h2>
|
|
||||||
<p className="text-xl mb-8 text-primary-100">
|
|
||||||
Join thousands of businesses using QR Master to track and optimize their QR code campaigns
|
|
||||||
</p>
|
|
||||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
|
||||||
<Link href="/signup">
|
|
||||||
<Button size="lg" variant="secondary" className="text-lg px-8 py-4 w-full sm:w-auto bg-white text-primary-600 hover:bg-gray-100">
|
|
||||||
Create Free Account
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
<Link href="/pricing">
|
|
||||||
<Button size="lg" variant="outline" className="text-lg px-8 py-4 w-full sm:w-auto border-white text-white hover:bg-white/10">
|
|
||||||
View Pricing
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
</section>
|
|
||||||
|
{/* CTA Section */}
|
||||||
|
<section className="py-20 bg-gradient-to-r from-primary-600 to-purple-600 text-white">
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-4xl text-center">
|
||||||
|
<h2 className="text-4xl font-bold mb-6">
|
||||||
|
Start Tracking Your QR Codes Today
|
||||||
|
</h2>
|
||||||
|
<p className="text-xl mb-8 text-primary-100">
|
||||||
|
Join thousands of businesses using QR Master to track and optimize their QR code campaigns
|
||||||
|
</p>
|
||||||
|
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||||
|
<Link href="/signup">
|
||||||
|
<Button size="lg" variant="secondary" className="text-lg px-8 py-4 w-full sm:w-auto bg-white text-primary-600 hover:bg-gray-100">
|
||||||
|
Create Free Account
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
<Link href="/pricing">
|
||||||
|
<Button size="lg" variant="outline" className="text-lg px-8 py-4 w-full sm:w-auto border-white text-white hover:bg-white/10">
|
||||||
|
View Pricing
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ export default function PhoneGenerator() {
|
||||||
const { toPng } = await import('html-to-image');
|
const { toPng } = await import('html-to-image');
|
||||||
const dataUrl = await toPng(qrRef.current, { cacheBust: true, pixelRatio: 3 });
|
const dataUrl = await toPng(qrRef.current, { cacheBust: true, pixelRatio: 3 });
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
link.download = `phone-qr-code.png`;
|
link.download = `call-qr-code.png`;
|
||||||
link.href = dataUrl;
|
link.href = dataUrl;
|
||||||
link.click();
|
link.click();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -67,7 +67,7 @@ export default function PhoneGenerator() {
|
||||||
const url = URL.createObjectURL(blob);
|
const url = URL.createObjectURL(blob);
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
link.href = url;
|
link.href = url;
|
||||||
link.download = `phone-qr-code.svg`;
|
link.download = `call-qr-code.svg`;
|
||||||
link.click();
|
link.click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -95,11 +95,11 @@ export default function PhoneGenerator() {
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<h2 className="text-lg font-bold text-slate-900 flex items-center gap-2">
|
<h2 className="text-lg font-bold text-slate-900 flex items-center gap-2">
|
||||||
<Phone className="w-5 h-5 text-[#1A1265]" />
|
<Phone className="w-5 h-5 text-[#1A1265]" />
|
||||||
Phone Number
|
Call Number
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-slate-700 mb-2">Number</label>
|
<label className="block text-sm font-medium text-slate-700 mb-2">Number to Call</label>
|
||||||
<Input
|
<Input
|
||||||
placeholder="+1 (555) 123-4567"
|
placeholder="+1 (555) 123-4567"
|
||||||
value={phone}
|
value={phone}
|
||||||
|
|
@ -222,7 +222,7 @@ export default function PhoneGenerator() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="text-xs text-slate-600 mt-4 text-center">
|
<p className="text-xs text-slate-600 mt-4 text-center">
|
||||||
Scanning initiates a call on any mobile phone.
|
Scanning initiates a direct call on any mobile phone.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -7,26 +7,26 @@ import { ToolBreadcrumb } from '@/components/seo/BreadcrumbSchema';
|
||||||
import { RelatedTools } from '@/components/marketing/RelatedTools';
|
import { RelatedTools } from '@/components/marketing/RelatedTools';
|
||||||
import { generateSoftwareAppSchema, generateFaqSchema } from '@/lib/schema-utils';
|
import { generateSoftwareAppSchema, generateFaqSchema } from '@/lib/schema-utils';
|
||||||
|
|
||||||
// SEO Optimized Metadata
|
// SEO Optimized Metadata for "Call QR Code"
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: {
|
title: {
|
||||||
absolute: 'Free Phone QR Code Generator | Anruf & Telefon QR | QR Master',
|
absolute: 'Free Call QR Code Generator | Click-to-Call & Phone QR | QR Master',
|
||||||
},
|
},
|
||||||
description: 'Create a QR code that makes a phone call. Anruf und Telefonat starten per Scan. Perfect for business cards & support. Kostenlos Call-QR erstellen.',
|
description: 'Create Action-Oriented Call QR Codes. Scanners instantly dial your number. Perfect for "Call Now" buttons on print & flyers. Free & No Signup.',
|
||||||
keywords: ['phone qr code', 'call qr code', 'phone number qr generator', 'click to call qr', 'business card qr code', 'telefon qr code', 'anruf qr code', 'qr code telefonnummer', 'anruf starten qr code', 'telefonnummer scannen'],
|
keywords: ['call qr code', 'click to call qr code', 'call now qr code', 'phone call qr generator', 'qr code for calling', 'call me qr', 'direct call qr code', 'dialer qr code', 'telefon qr code', 'anruf qr code'],
|
||||||
alternates: {
|
alternates: {
|
||||||
canonical: 'https://www.qrmaster.net/tools/phone-qr-code',
|
canonical: 'https://www.qrmaster.net/tools/call-qr-code-generator',
|
||||||
},
|
},
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: 'Free Phone QR Code Generator | QR Master',
|
title: 'Free Call QR Code Generator | Click-to-Call | QR Master',
|
||||||
description: 'Generate QR codes to initiate phone calls instantly. Share your number easily.',
|
description: 'Generate Click-to-Call QR Codes. One scan to start a phone call instantly. Best for flyers and business cards.',
|
||||||
type: 'website',
|
type: 'website',
|
||||||
url: 'https://www.qrmaster.net/tools/phone-qr-code',
|
url: 'https://www.qrmaster.net/tools/call-qr-code-generator',
|
||||||
images: [{ url: '/og-phone-generator.png', width: 1200, height: 630 }],
|
images: [{ url: '/og-phone-generator.png', width: 1200, height: 630 }],
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
card: 'summary_large_image',
|
card: 'summary_large_image',
|
||||||
title: 'Free Phone QR Code Generator',
|
title: 'Free Call QR Code Generator | Start Calls with a Scan',
|
||||||
description: 'Create QR codes for instant calling. Free and reliable.',
|
description: 'Create QR codes for instant calling. Free and reliable.',
|
||||||
},
|
},
|
||||||
robots: {
|
robots: {
|
||||||
|
|
@ -40,13 +40,13 @@ const jsonLd = {
|
||||||
'@context': 'https://schema.org',
|
'@context': 'https://schema.org',
|
||||||
'@graph': [
|
'@graph': [
|
||||||
generateSoftwareAppSchema(
|
generateSoftwareAppSchema(
|
||||||
'Phone QR Code Generator',
|
'Call QR Code Generator',
|
||||||
'Generate QR codes that trigger a phone call when scanned on a mobile device.',
|
'Generate QR codes that trigger a phone call when scanned on a mobile device.',
|
||||||
'/og-phone-generator.png'
|
'/og-phone-generator.png'
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
'@type': 'HowTo',
|
'@type': 'HowTo',
|
||||||
name: 'How to Create a Phone QR Code',
|
name: 'How to Create a Call QR Code',
|
||||||
description: 'Create a QR code that dials a number automatically.',
|
description: 'Create a QR code that dials a number automatically.',
|
||||||
step: [
|
step: [
|
||||||
{
|
{
|
||||||
|
|
@ -65,7 +65,7 @@ const jsonLd = {
|
||||||
'@type': 'HowToStep',
|
'@type': 'HowToStep',
|
||||||
position: 3,
|
position: 3,
|
||||||
name: 'Download',
|
name: 'Download',
|
||||||
text: 'Save the QR code and print it on your materials.',
|
text: 'Save the "Call Now" QR code and print it on your materials.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'@type': 'HowToStep',
|
'@type': 'HowToStep',
|
||||||
|
|
@ -85,7 +85,7 @@ const jsonLd = {
|
||||||
generateFaqSchema({
|
generateFaqSchema({
|
||||||
'Does it call automatically?': {
|
'Does it call automatically?': {
|
||||||
question: 'Does it call automatically?',
|
question: 'Does it call automatically?',
|
||||||
answer: 'Scanning the QR code opens the phone dialer with the number pre-filled. The user must tap the call button to initiate the call.',
|
answer: 'Scanning the QR code opens the phone dialer with the number pre-filled. The user must tap the call button to initiate the call (security feature of phones).',
|
||||||
},
|
},
|
||||||
'Does it work internationally?': {
|
'Does it work internationally?': {
|
||||||
question: 'Does it work internationally?',
|
question: 'Does it work internationally?',
|
||||||
|
|
@ -97,7 +97,7 @@ const jsonLd = {
|
||||||
},
|
},
|
||||||
'Can I track calls?': {
|
'Can I track calls?': {
|
||||||
question: 'Can I track calls?',
|
question: 'Can I track calls?',
|
||||||
answer: 'This static QR code cannot track calls. For tracking scans and analytics, consider using our Dynamic QR Code solution.',
|
answer: 'This static Call QR Code cannot track calls. For tracking scans and analytics, consider using our VCard Plus solution.',
|
||||||
},
|
},
|
||||||
'Is it free?': {
|
'Is it free?': {
|
||||||
question: 'Is it free?',
|
question: 'Is it free?',
|
||||||
|
|
@ -107,14 +107,14 @@ const jsonLd = {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function PhoneQRCodePage() {
|
export default function CallQRCodePage() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<script
|
<script
|
||||||
type="application/ld+json"
|
type="application/ld+json"
|
||||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
||||||
/>
|
/>
|
||||||
<ToolBreadcrumb toolName="Phone QR Code Generator" toolSlug="phone-qr-code" />
|
<ToolBreadcrumb toolName="Call QR Code Generator" toolSlug="call-qr-code-generator" />
|
||||||
|
|
||||||
<div className="min-h-screen" style={{ backgroundColor: '#EBEBDF' }}>
|
<div className="min-h-screen" style={{ backgroundColor: '#EBEBDF' }}>
|
||||||
|
|
||||||
|
|
@ -144,11 +144,11 @@ export default function PhoneQRCodePage() {
|
||||||
|
|
||||||
<h1 className="text-4xl md:text-5xl lg:text-6xl font-extrabold text-white tracking-tight leading-tight mb-6">
|
<h1 className="text-4xl md:text-5xl lg:text-6xl font-extrabold text-white tracking-tight leading-tight mb-6">
|
||||||
Create Instant <br className="hidden lg:block" />
|
Create Instant <br className="hidden lg:block" />
|
||||||
<span className="text-transparent bg-clip-text bg-gradient-to-r from-emerald-400 to-cyan-400">Call-to-Action QR Codes</span>
|
<span className="text-transparent bg-clip-text bg-gradient-to-r from-emerald-400 to-cyan-400">"Call Now" QR Codes</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p className="text-lg md:text-xl text-indigo-100 max-w-2xl mx-auto lg:mx-0 mb-8 leading-relaxed">
|
<p className="text-lg md:text-xl text-indigo-100 max-w-2xl mx-auto lg:mx-0 mb-8 leading-relaxed">
|
||||||
Make it easy for customers to call you. Scan to dial instantly.
|
The #1 Tool for Click-to-Call QR Codes. Scanners instantly open their phone dialer with your number pre-filled.
|
||||||
<strong className="text-white block sm:inline mt-2 sm:mt-0"> Perfect for print marketing.</strong>
|
<strong className="text-white block sm:inline mt-2 sm:mt-0"> Perfect for print marketing.</strong>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -215,7 +215,7 @@ export default function PhoneQRCodePage() {
|
||||||
<section className="py-16 px-4 sm:px-6 lg:px-8 bg-white">
|
<section className="py-16 px-4 sm:px-6 lg:px-8 bg-white">
|
||||||
<div className="max-w-4xl mx-auto">
|
<div className="max-w-4xl mx-auto">
|
||||||
<h2 className="text-3xl font-bold text-slate-900 text-center mb-12">
|
<h2 className="text-3xl font-bold text-slate-900 text-center mb-12">
|
||||||
How Phone QR Codes Work
|
How Call QR Codes Work
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div className="grid md:grid-cols-3 lg:grid-cols-5 gap-8">
|
<div className="grid md:grid-cols-3 lg:grid-cols-5 gap-8">
|
||||||
|
|
@ -282,7 +282,7 @@ export default function PhoneQRCodePage() {
|
||||||
Frequently Asked Questions
|
Frequently Asked Questions
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-slate-600 text-center mb-10">
|
<p className="text-slate-600 text-center mb-10">
|
||||||
Common questions about Phone QR codes.
|
Common questions about Call QR codes.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
|
|
@ -292,11 +292,11 @@ export default function PhoneQRCodePage() {
|
||||||
/>
|
/>
|
||||||
<FaqItem
|
<FaqItem
|
||||||
question="Does this work on iPhone and Android?"
|
question="Does this work on iPhone and Android?"
|
||||||
answer="Yes, Phone QR codes are a standard format supported natively by iOS and Android camera apps."
|
answer="Yes, Call QR codes are a standard format supported natively by iOS and Android camera apps."
|
||||||
/>
|
/>
|
||||||
<FaqItem
|
<FaqItem
|
||||||
question="Can I change the number later?"
|
question="Can I change the number later?"
|
||||||
answer="No. Static QR codes can't be edited. If your phone number changes, you'll need a new QR code. Use a Dynamic QR Code if you anticipate changes."
|
answer="No. Static Call QR codes can't be edited. If your phone number changes, you'll need a new QR code. Use a Dynamic QR Code if you anticipate changes."
|
||||||
/>
|
/>
|
||||||
<FaqItem
|
<FaqItem
|
||||||
question="Is there a cost per scan?"
|
question="Is there a cost per scan?"
|
||||||
|
|
@ -50,7 +50,7 @@ export default function MarketingLayout({
|
||||||
{ name: 'WhatsApp', description: 'Start a chat', href: '/tools/whatsapp-qr-code', icon: MessageCircle, color: 'text-green-500', bgColor: 'bg-green-50' },
|
{ name: 'WhatsApp', description: 'Start a chat', href: '/tools/whatsapp-qr-code', icon: MessageCircle, color: 'text-green-500', bgColor: 'bg-green-50' },
|
||||||
{ name: 'Email', description: 'Compose an email', href: '/tools/email-qr-code', icon: Mail, color: 'text-amber-500', bgColor: 'bg-amber-50' },
|
{ name: 'Email', description: 'Compose an email', href: '/tools/email-qr-code', icon: Mail, color: 'text-amber-500', bgColor: 'bg-amber-50' },
|
||||||
{ name: 'SMS', description: 'Send a text message', href: '/tools/sms-qr-code', icon: MessageSquare, color: 'text-cyan-500', bgColor: 'bg-cyan-50' },
|
{ name: 'SMS', description: 'Send a text message', href: '/tools/sms-qr-code', icon: MessageSquare, color: 'text-cyan-500', bgColor: 'bg-cyan-50' },
|
||||||
{ name: 'Phone', description: 'Start a call', href: '/tools/phone-qr-code', icon: Phone, color: 'text-violet-500', bgColor: 'bg-violet-50' },
|
{ name: 'Call', description: 'Anruf starten', href: '/tools/call-qr-code-generator', icon: Phone, color: 'text-violet-500', bgColor: 'bg-violet-50' },
|
||||||
{ name: 'Event', description: 'Add calendar event', href: '/tools/event-qr-code', icon: Calendar, color: 'text-red-500', bgColor: 'bg-red-50' },
|
{ name: 'Event', description: 'Add calendar event', href: '/tools/event-qr-code', icon: Calendar, color: 'text-red-500', bgColor: 'bg-red-50' },
|
||||||
{ name: 'Location', description: 'Share a place', href: '/tools/geolocation-qr-code', icon: MapPin, color: 'text-emerald-500', bgColor: 'bg-emerald-50' },
|
{ name: 'Location', description: 'Share a place', href: '/tools/geolocation-qr-code', icon: MapPin, color: 'text-emerald-500', bgColor: 'bg-emerald-50' },
|
||||||
{ name: 'Facebook', description: 'Facebook profile/page', href: '/tools/facebook-qr-code', icon: Facebook, color: 'text-blue-600', bgColor: 'bg-blue-50' },
|
{ name: 'Facebook', description: 'Facebook profile/page', href: '/tools/facebook-qr-code', icon: Facebook, color: 'text-blue-600', bgColor: 'bg-blue-50' },
|
||||||
|
|
@ -85,7 +85,7 @@ export default function MarketingLayout({
|
||||||
<li><a href="/tools/whatsapp-qr-code">WhatsApp QR Code</a></li>
|
<li><a href="/tools/whatsapp-qr-code">WhatsApp QR Code</a></li>
|
||||||
<li><a href="/tools/email-qr-code">Email QR Code</a></li>
|
<li><a href="/tools/email-qr-code">Email QR Code</a></li>
|
||||||
<li><a href="/tools/sms-qr-code">SMS QR Code</a></li>
|
<li><a href="/tools/sms-qr-code">SMS QR Code</a></li>
|
||||||
<li><a href="/tools/phone-qr-code">Telefon QR Code</a></li>
|
<li><a href="/tools/call-qr-code-generator">Call / Anruf QR Code</a></li>
|
||||||
<li><a href="/tools/event-qr-code">Event QR Code</a></li>
|
<li><a href="/tools/event-qr-code">Event QR Code</a></li>
|
||||||
<li><a href="/tools/geolocation-qr-code">Standort QR Code</a></li>
|
<li><a href="/tools/geolocation-qr-code">Standort QR Code</a></li>
|
||||||
<li><a href="/tools/facebook-qr-code">Facebook QR Code</a></li>
|
<li><a href="/tools/facebook-qr-code">Facebook QR Code</a></li>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
import React from 'react';
|
||||||
|
import type { Metadata } from 'next';
|
||||||
|
import { Hero } from '@/components/marketing/Hero'; // Re-use simplified version or dedicated FeaturesHero
|
||||||
|
import { Features } from '@/components/marketing/Features';
|
||||||
|
import { StaticVsDynamic } from '@/components/marketing/StaticVsDynamic';
|
||||||
|
import { Pricing } from '@/components/marketing/Pricing';
|
||||||
|
import en from '@/i18n/en.json';
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'QR Master Features | Tracking, Analytics & Bulk Generation',
|
||||||
|
description: 'Explore QR Master features: Dynamic QR codes, real-time analytics, bulk generation, custom branding, and API access.',
|
||||||
|
alternates: {
|
||||||
|
canonical: 'https://www.qrmaster.net/features',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function FeaturesPage() {
|
||||||
|
const t = en;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="pt-20">
|
||||||
|
<section className="bg-gradient-to-b from-slate-50 to-white py-20 px-4">
|
||||||
|
<div className="container mx-auto text-center max-w-4xl">
|
||||||
|
<h1 className="text-4xl md:text-5xl font-bold mb-6 text-slate-900">
|
||||||
|
Everything You Need <br /> to Run Successful QR Campaigns
|
||||||
|
</h1>
|
||||||
|
<p className="text-xl text-slate-600 mb-8">
|
||||||
|
From basic static codes to enterprise-grade dynamic tracking.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<StaticVsDynamic t={t} />
|
||||||
|
<Features t={t} />
|
||||||
|
|
||||||
|
{/* Additional Detail Sections could go here */}
|
||||||
|
|
||||||
|
<div className="py-20 bg-slate-50">
|
||||||
|
<Pricing t={t} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import type { Metadata } from 'next';
|
||||||
|
import en from '@/i18n/en.json';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import SeoJsonLd from '@/components/SeoJsonLd';
|
||||||
|
import { articleSchema } from '@/lib/schema';
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'How to Bulk Generate QR Codes (CSV/Excel) | QR Master',
|
||||||
|
description: 'Learn how to create hundreds of QR codes at once using a CSV or Excel file. Free bulk QR code generator guide.',
|
||||||
|
alternates: {
|
||||||
|
canonical: 'https://www.qrmaster.net/guide/bulk-qr-code-generation',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function BulkGuidePage() {
|
||||||
|
return (
|
||||||
|
<div className="pt-20 bg-white">
|
||||||
|
<SeoJsonLd data={[
|
||||||
|
articleSchema({
|
||||||
|
headline: 'How to Bulk Generate QR Codes from CSV/Excel',
|
||||||
|
description: 'Step-by-step guide to generating hundreds of QR codes automatically using spreadsheet data.',
|
||||||
|
image: 'https://www.qrmaster.net/og-bulk-guide.png',
|
||||||
|
datePublished: '2025-10-15',
|
||||||
|
dateModified: '2025-10-15',
|
||||||
|
author: 'QR Master Team',
|
||||||
|
url: 'https://www.qrmaster.net/guide/bulk-qr-code-generation'
|
||||||
|
})
|
||||||
|
]} />
|
||||||
|
<article className="max-w-4xl mx-auto px-4 py-20">
|
||||||
|
<header className="mb-12 text-center">
|
||||||
|
<span className="text-sm font-semibold text-indigo-600 tracking-wide uppercase">Efficiency Guide</span>
|
||||||
|
<h1 className="text-4xl md:text-5xl font-bold text-slate-900 mt-2 mb-6">
|
||||||
|
How to Bulk Generate QR Codes
|
||||||
|
</h1>
|
||||||
|
<p className="text-xl text-slate-600">
|
||||||
|
Turn your spreadsheet into hundreds of QR codes in seconds.
|
||||||
|
</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div className="prose prose-lg prose-slate mx-auto">
|
||||||
|
<p>
|
||||||
|
Need to create unique QR codes for 100 employees? Or 500 product labels? Manually creating them one by one is a waste of time. Instead, use our <strong>Bulk Creation</strong> tool.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Step 1: Prepare your data</h2>
|
||||||
|
<p>
|
||||||
|
Create a CSV or Excel file (XLSX) with two columns:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Title:</strong> A name for the file (e.g., "Employee 001")</li>
|
||||||
|
<li><strong>Content:</strong> The URL or text for the QR code (e.g., "https://yoursite.com/emp/001")</li>
|
||||||
|
</ul>
|
||||||
|
<div className="bg-slate-100 p-4 rounded-lg text-sm font-mono mb-4">
|
||||||
|
Title,Content<br />
|
||||||
|
Item-1,https://example.com/1<br />
|
||||||
|
Item-2,https://example.com/2<br />
|
||||||
|
Item-3,https://example.com/3
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Step 2: Upload to QR Master</h2>
|
||||||
|
<ol>
|
||||||
|
<li>Go to the <Link href="/bulk-qr-code-generator" className="text-indigo-600 hover:underline">Bulk Generator</Link> page.</li>
|
||||||
|
<li>Drag and drop your CSV/Excel file.</li>
|
||||||
|
<li>Review the preview to ensure columns are mapped correctly.</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h2>Step 3: Customize & Download</h2>
|
||||||
|
<p>
|
||||||
|
Set your brand colors, logo, and style. This style will be applied to <strong>all</strong> generated QR codes across the batch.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Finally, click <strong>Generate</strong>. You will receive a ZIP file containing:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>All QR codes as individual PNG or SVG files.</li>
|
||||||
|
<li>Filenames matching your "Title" column for easy organization.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Limits & Pricing</h2>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Free Plan:</strong> You can bulk generate limits for Static codes (no tracking).</li>
|
||||||
|
<li><strong>Business Plan:</strong> Unlocks Bulk Dynamic Codes (trackable) and higher limits (up to 1,000 at a time).</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-16 text-center">
|
||||||
|
<Link href="/bulk-qr-code-generator">
|
||||||
|
<button className="bg-indigo-600 text-white px-8 py-3 rounded-full font-bold text-lg hover:bg-indigo-700 transition-colors">
|
||||||
|
Start Bulk Generation
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import type { Metadata } from 'next';
|
||||||
|
import en from '@/i18n/en.json';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import SeoJsonLd from '@/components/SeoJsonLd';
|
||||||
|
import { articleSchema } from '@/lib/schema';
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'QR Code Best Practices (Size, Color, Testing) | QR Master Guide',
|
||||||
|
description: 'Ensure your QR codes scan every time. Guide on minimum size, color contrast, error correction, and placement best practices.',
|
||||||
|
alternates: {
|
||||||
|
canonical: 'https://www.qrmaster.net/guide/qr-code-best-practices',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function BestPracticesGuidePage() {
|
||||||
|
return (
|
||||||
|
<div className="pt-20 bg-white">
|
||||||
|
<SeoJsonLd data={[
|
||||||
|
articleSchema({
|
||||||
|
headline: 'QR Code Design Best Practices: The Ultimate Checklist',
|
||||||
|
description: 'Ensure your QR codes scan perfectly. Tips on size, contrast, and error correction levels.',
|
||||||
|
image: 'https://www.qrmaster.net/og-best-practices.png',
|
||||||
|
datePublished: '2025-10-15',
|
||||||
|
dateModified: '2025-10-15',
|
||||||
|
author: 'QR Master Team',
|
||||||
|
url: 'https://www.qrmaster.net/guide/qr-code-best-practices'
|
||||||
|
})
|
||||||
|
]} />
|
||||||
|
<article className="max-w-4xl mx-auto px-4 py-20">
|
||||||
|
<header className="mb-12 text-center">
|
||||||
|
<span className="text-sm font-semibold text-indigo-600 tracking-wide uppercase">Design Guide</span>
|
||||||
|
<h1 className="text-4xl md:text-5xl font-bold text-slate-900 mt-2 mb-6">
|
||||||
|
7 Rules for Perfect QR Codes
|
||||||
|
</h1>
|
||||||
|
<p className="text-xl text-slate-600">
|
||||||
|
Don't let a bad design kill your campaign. Follow these scanning rules.
|
||||||
|
</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div className="prose prose-lg prose-slate mx-auto">
|
||||||
|
<h3>1. Size Matters</h3>
|
||||||
|
<p>
|
||||||
|
<strong>Minimum size:</strong> 2cm x 2cm (0.8" x 0.8") for dynamic codes.
|
||||||
|
If scanning from a distance (e.g., billboard), the QR code size should be 1/10th of the scanning distance (scan from 10m -> 1m wide code).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>2. High Contrast is Key</h3>
|
||||||
|
<p>
|
||||||
|
Always use a <strong>dark foreground</strong> on a <strong>light background</strong>. Most scanners expect this.
|
||||||
|
<br />
|
||||||
|
✅ Black on White
|
||||||
|
<br />
|
||||||
|
✅ Dark Blue on White
|
||||||
|
<br />
|
||||||
|
❌ White on Black (Inverted - some older scanners fail)
|
||||||
|
<br />
|
||||||
|
❌ Light Grey on White (Low contrast)
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>3. Leave a Quiet Zone</h3>
|
||||||
|
<p>
|
||||||
|
The "Quiet Zone" is the whitespace border around the QR code. It helps the scanner distinguish the code from the surroundings. Never print right to the edge of the pixels.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>4. Error Correction Level</h3>
|
||||||
|
<p>
|
||||||
|
If you add a logo to the center, raise the Error Correction Level to <strong>High (H)</strong> or <strong>Quartile (Q)</strong>. This adds redundant data so the code is readable even if 30% is covered by your logo.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>5. Don't Overstuff Static Codes</h3>
|
||||||
|
<p>
|
||||||
|
Static QR codes grow more complex (more dots) as you add data. A URL with 200 characters makes a dense, hard-to-scan code. Use a <strong>URL Shortener</strong> or <strong>Dynamic QR Code</strong> to keep the pattern simple.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>6. Call to Action (CTA)</h3>
|
||||||
|
<p>
|
||||||
|
Don't just print a code. Tell users <strong>why</strong> they should scan.
|
||||||
|
<br />
|
||||||
|
<em>"Scan for Menu"</em>
|
||||||
|
<br />
|
||||||
|
<em>"Scan to Win"</em>
|
||||||
|
<br />
|
||||||
|
Frame your QR code with a clear CTA.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>7. Test, Test, Test</h3>
|
||||||
|
<p>
|
||||||
|
Print a sample. Scan it with an iPhone. Scan it with an Android. Scan it in low light. Never assume it works until you verify it physically.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-16 text-center">
|
||||||
|
<Link href="/create-qr-code">
|
||||||
|
<button className="bg-indigo-600 text-white px-8 py-3 rounded-full font-bold text-lg hover:bg-indigo-700 transition-colors">
|
||||||
|
Create a Perfect QR Code
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import type { Metadata } from 'next';
|
||||||
|
import { Hero } from '@/components/marketing/Hero';
|
||||||
|
import { Features } from '@/components/marketing/Features';
|
||||||
|
import { FAQ } from '@/components/marketing/FAQ';
|
||||||
|
import en from '@/i18n/en.json';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import SeoJsonLd from '@/components/SeoJsonLd';
|
||||||
|
import { articleSchema } from '@/lib/schema';
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'How to Track QR Code Scans (GA4 + UTM) | QR Master Guide',
|
||||||
|
description: 'Learn how to track QR code scans using Google Analytics 4 (GA4), UTM parameters, and QR Master\'s built-in analytics. Step-by-step guide.',
|
||||||
|
alternates: {
|
||||||
|
canonical: 'https://www.qrmaster.net/guide/tracking-analytics',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function TrackingGuidePage() {
|
||||||
|
return (
|
||||||
|
<div className="pt-20 bg-white">
|
||||||
|
<SeoJsonLd data={[
|
||||||
|
articleSchema({
|
||||||
|
headline: 'How to Track QR Code Scans: The Definitive Guide (2025)',
|
||||||
|
description: 'From basic click counts to advanced Google Analytics 4 integration. Learn to track every scan.',
|
||||||
|
image: 'https://www.qrmaster.net/og-tracking-guide.png',
|
||||||
|
datePublished: '2025-10-15',
|
||||||
|
dateModified: '2025-10-15',
|
||||||
|
author: 'QR Master Team',
|
||||||
|
url: 'https://www.qrmaster.net/guide/tracking-analytics'
|
||||||
|
})
|
||||||
|
]} />
|
||||||
|
<article className="max-w-4xl mx-auto px-4 py-20">
|
||||||
|
<header className="mb-12 text-center">
|
||||||
|
<span className="text-sm font-semibold text-indigo-600 tracking-wide uppercase">Complete Guide</span>
|
||||||
|
<h1 className="text-4xl md:text-5xl font-bold text-slate-900 mt-2 mb-6">
|
||||||
|
How to Track QR Code Scans: The Definitive Guide (2025)
|
||||||
|
</h1>
|
||||||
|
<p className="text-xl text-slate-600">
|
||||||
|
From basic click counts to advanced Google Analytics 4 integration.
|
||||||
|
</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div className="prose prose-lg prose-slate mx-auto">
|
||||||
|
<div className="bg-indigo-50 border-l-4 border-indigo-500 p-6 rounded-r-lg mb-12">
|
||||||
|
<h3 className="text-indigo-900 font-bold text-lg m-0 mb-2">🚀 Quick Answer</h3>
|
||||||
|
<p className="text-indigo-800 m-0">
|
||||||
|
To track QR code scans, you generally need a <strong>Dynamic QR Code</strong>. It redirects users through a short URL (like <code>qr.do/xyz</code>) which counts the scan before sending them to your destination. For advanced data, add <strong>UTM parameters</strong> to your URL to see traffic in Google Analytics 4.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Method 1: Built-in Tracking (Easiest)</h2>
|
||||||
|
<p>
|
||||||
|
QR Master provides built-in analytics for all Dynamic QR Codes. This is the simplest way to see:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Total Scans:</strong> How many times your code was scanned.</li>
|
||||||
|
<li><strong>Unique Scans:</strong> How many individual people scanned it.</li>
|
||||||
|
<li><strong>Location:</strong> City and country of the scanner.</li>
|
||||||
|
<li><strong>Device:</strong> iPhone, Android, Desktop, etc.</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
<Link href="/dynamic-qr-code-generator" className="text-indigo-600 hover:underline">Create a Dynamic QR Code</Link> to start tracking instantly.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Method 2: Google Analytics 4 (Advanced)</h2>
|
||||||
|
<p>
|
||||||
|
If you want to track what users <em>do</em> after scanning (e.g., did they buy something?), you should use UTM parameters.
|
||||||
|
</p>
|
||||||
|
<h3>Step 1: Build your URL</h3>
|
||||||
|
<p>Instead of using `https://yoursite.com`, add parameters:</p>
|
||||||
|
<code className="block bg-slate-800 text-white p-4 rounded-lg text-sm overflow-x-auto mb-4">
|
||||||
|
https://yoursite.com?utm_source=qr_code&utm_medium=offline&utm_campaign=summer_menu
|
||||||
|
</code>
|
||||||
|
|
||||||
|
<h3>Step 2: Generate the QR Code</h3>
|
||||||
|
<p>Paste this long URL into the <Link href="/" className="text-indigo-600 hover:underline">QR generator</Link>. Now, when scanning:</p>
|
||||||
|
<ol>
|
||||||
|
<li>The user goes to your specific tagged URL.</li>
|
||||||
|
<li>GA4 records a session with `source: qr_code`.</li>
|
||||||
|
<li>You can see exactly how much revenue that specific QR code generated.</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h2>Common Pitfalls</h2>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Forgot to test:</strong> Always scan your code <em>before</em> printing 1,000 copies.</li>
|
||||||
|
<li><strong>QR Code too small:</strong> Ensure it's at least 2cm x 2cm (0.8" x 0.8") for short distance scanning.</li>
|
||||||
|
<li><strong>Using Static Codes for Tracking:</strong> Static codes link directly. We cannot track them unless you use Method 2 (UTM) and check your own server logs.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-16 text-center">
|
||||||
|
<Link href="/dynamic-qr-code-generator">
|
||||||
|
<button className="bg-indigo-600 text-white px-8 py-3 rounded-full font-bold text-lg hover:bg-indigo-700 transition-colors">
|
||||||
|
Create Trackable QR Code Free
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -21,7 +21,7 @@ export default function sitemap(): MetadataRoute.Sitemap {
|
||||||
'whatsapp-qr-code',
|
'whatsapp-qr-code',
|
||||||
'tiktok-qr-code',
|
'tiktok-qr-code',
|
||||||
'geolocation-qr-code',
|
'geolocation-qr-code',
|
||||||
'phone-qr-code',
|
'call-qr-code-generator',
|
||||||
'paypal-qr-code',
|
'paypal-qr-code',
|
||||||
'zoom-qr-code',
|
'zoom-qr-code',
|
||||||
'teams-qr-code',
|
'teams-qr-code',
|
||||||
|
|
@ -80,12 +80,36 @@ export default function sitemap(): MetadataRoute.Sitemap {
|
||||||
changeFrequency: 'monthly',
|
changeFrequency: 'monthly',
|
||||||
priority: 0.9,
|
priority: 0.9,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/custom-qr-code-generator`,
|
||||||
|
lastModified: new Date(),
|
||||||
|
changeFrequency: 'weekly',
|
||||||
|
priority: 0.9,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/manage-qr-codes`,
|
||||||
|
lastModified: new Date(),
|
||||||
|
changeFrequency: 'weekly',
|
||||||
|
priority: 0.9,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
url: `${baseUrl}/pricing`,
|
url: `${baseUrl}/pricing`,
|
||||||
lastModified: new Date(),
|
lastModified: new Date(),
|
||||||
changeFrequency: 'monthly',
|
changeFrequency: 'monthly',
|
||||||
priority: 0.8,
|
priority: 0.8,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/tools`,
|
||||||
|
lastModified: new Date(),
|
||||||
|
changeFrequency: 'monthly',
|
||||||
|
priority: 0.9,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/features`,
|
||||||
|
lastModified: new Date(),
|
||||||
|
changeFrequency: 'monthly',
|
||||||
|
priority: 0.8,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
url: `${baseUrl}/faq`,
|
url: `${baseUrl}/faq`,
|
||||||
lastModified: new Date(),
|
lastModified: new Date(),
|
||||||
|
|
@ -116,6 +140,24 @@ export default function sitemap(): MetadataRoute.Sitemap {
|
||||||
changeFrequency: 'yearly',
|
changeFrequency: 'yearly',
|
||||||
priority: 0.4,
|
priority: 0.4,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/guide/tracking-analytics`,
|
||||||
|
lastModified: new Date(),
|
||||||
|
changeFrequency: 'monthly',
|
||||||
|
priority: 0.8,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/guide/bulk-qr-code-generation`,
|
||||||
|
lastModified: new Date(),
|
||||||
|
changeFrequency: 'monthly',
|
||||||
|
priority: 0.8,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/guide/qr-code-best-practices`,
|
||||||
|
lastModified: new Date(),
|
||||||
|
changeFrequency: 'monthly',
|
||||||
|
priority: 0.8,
|
||||||
|
},
|
||||||
|
|
||||||
...toolPages,
|
...toolPages,
|
||||||
...blogPages,
|
...blogPages,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
import React from 'react';
|
||||||
|
import type { Metadata } from 'next';
|
||||||
|
import { FreeToolsGrid } from '@/components/marketing/FreeToolsGrid';
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'Free QR Code Tools | URL, vCard, WiFi & More | QR Master',
|
||||||
|
description: 'Access our complete collection of free QR code generators. Create codes for URLs, WiFi, plain text, vCards, and more. No signup required for static codes.',
|
||||||
|
alternates: {
|
||||||
|
canonical: 'https://www.qrmaster.net/tools',
|
||||||
|
},
|
||||||
|
openGraph: {
|
||||||
|
title: 'Free QR Code Tools Collection',
|
||||||
|
description: 'All your QR code needs in one place. Free forever static codes.',
|
||||||
|
url: 'https://www.qrmaster.net/tools',
|
||||||
|
siteName: 'QR Master',
|
||||||
|
type: 'website',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ToolsHubPage() {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-slate-50 pt-20">
|
||||||
|
<section className="bg-white py-20 px-4 border-b border-slate-200">
|
||||||
|
<div className="container mx-auto text-center max-w-4xl">
|
||||||
|
<span className="inline-block px-4 py-1.5 rounded-full bg-indigo-50 text-indigo-700 font-semibold text-sm mb-6">
|
||||||
|
100% Free Forever
|
||||||
|
</span>
|
||||||
|
<h1 className="text-4xl md:text-6xl font-extrabold text-slate-900 mb-6 tracking-tight">
|
||||||
|
Free QR Code Tools
|
||||||
|
</h1>
|
||||||
|
<p className="text-xl text-slate-600 mb-8 leading-relaxed max-w-2xl mx-auto">
|
||||||
|
Generate static QR codes for any purpose. No credit card, no expiration, no hidden fees.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div className="py-12">
|
||||||
|
<FreeToolsGrid />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section className="py-20 px-4">
|
||||||
|
<div className="container mx-auto max-w-3xl text-center">
|
||||||
|
<h2 className="text-2xl font-bold text-slate-900 mb-4">Why are these tools free?</h2>
|
||||||
|
<p className="text-slate-600 mb-8">
|
||||||
|
We believe basic QR codes should be accessible to everyone. Our static QR codes encode your data directly into the image,
|
||||||
|
meaning we don't need to host tracking servers for them. That's why they are free forever.
|
||||||
|
If you need tracking and editability, check out our Dynamic QR Codes.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -149,11 +149,11 @@ const TOOLS = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: Phone,
|
icon: Phone,
|
||||||
name: 'Phone',
|
name: 'Call',
|
||||||
description: 'Call phone number',
|
description: 'Start a phone call',
|
||||||
href: '/tools/phone-qr-code',
|
href: '/tools/call-qr-code-generator',
|
||||||
color: 'text-blue-400',
|
color: 'text-violet-500',
|
||||||
bg: 'bg-blue-50'
|
bg: 'bg-violet-50'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: CreditCard,
|
icon: CreditCard,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { QRCodeSVG } from 'qrcode.react';
|
||||||
|
import { Button } from '@/components/ui/Button';
|
||||||
|
import { Input } from '@/components/ui/Input';
|
||||||
|
import { Download, RefreshCw, Smartphone, Image as ImageIcon, ScanLine } from 'lucide-react';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
|
export function MiniGenerator() {
|
||||||
|
const [url, setUrl] = useState('');
|
||||||
|
const [color, setColor] = useState('#000000');
|
||||||
|
const [withLogo, setWithLogo] = useState(false);
|
||||||
|
const [frame, setFrame] = useState<'none' | 'scan_me' | 'phone'>('none');
|
||||||
|
const [mounted, setMounted] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setMounted(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Prevent hydration mismatch
|
||||||
|
if (!mounted) {
|
||||||
|
return (
|
||||||
|
<div className="bg-gray-100 rounded-lg p-8 mb-6 flex items-center justify-center min-h-[300px] animate-pulse">
|
||||||
|
<Smartphone className="w-16 h-16 text-gray-300" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderQR = () => (
|
||||||
|
<QRCodeSVG
|
||||||
|
value={url || 'https://www.qrmaster.net'}
|
||||||
|
size={180}
|
||||||
|
fgColor={color}
|
||||||
|
bgColor="#ffffff"
|
||||||
|
level="H" // High error correction for logo
|
||||||
|
includeMargin={false}
|
||||||
|
imageSettings={withLogo ? {
|
||||||
|
src: "/logo.svg", // Assuming this exists, or use a placeholder
|
||||||
|
x: undefined,
|
||||||
|
y: undefined,
|
||||||
|
height: 40,
|
||||||
|
width: 40,
|
||||||
|
excavate: true,
|
||||||
|
} : undefined}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col h-full">
|
||||||
|
<h3 className="font-semibold text-xl mb-6 text-center">Live Preview</h3>
|
||||||
|
|
||||||
|
<div className="flex-1 flex flex-col items-center justify-center space-y-6">
|
||||||
|
<div className="relative group">
|
||||||
|
{/* Frame Rendering */}
|
||||||
|
<div className={cn(
|
||||||
|
"bg-white p-4 rounded-xl shadow-lg transition-all duration-300",
|
||||||
|
frame === 'scan_me' && "pt-12 pb-4 px-4 bg-black rounded-lg",
|
||||||
|
frame === 'phone' && "p-2 border-8 border-gray-800 rounded-[2rem]"
|
||||||
|
)}>
|
||||||
|
{frame === 'scan_me' && (
|
||||||
|
<div className="absolute top-3 left-0 right-0 text-center text-white font-bold tracking-wider text-sm">
|
||||||
|
SCAN ME
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* White background for QR inside frames */}
|
||||||
|
<div className={cn(
|
||||||
|
"bg-white",
|
||||||
|
frame === 'scan_me' && "p-2 rounded",
|
||||||
|
frame === 'phone' && "rounded-2xl overflow-hidden"
|
||||||
|
)}>
|
||||||
|
{renderQR()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="w-full space-y-4">
|
||||||
|
<div>
|
||||||
|
<Input
|
||||||
|
placeholder="Enter your website URL..."
|
||||||
|
value={url}
|
||||||
|
onChange={(e) => setUrl(e.target.value)}
|
||||||
|
className="text-center"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Controls */}
|
||||||
|
<div className="flex flex-wrap gap-2 justify-center">
|
||||||
|
{/* Color Picker */}
|
||||||
|
<div className="flex items-center space-x-2 bg-gray-50 px-3 py-1.5 rounded-full border border-gray-200" title="Choose Color">
|
||||||
|
<div className="relative overflow-hidden w-6 h-6 rounded-full border border-gray-300 shadow-sm cursor-pointer hover:scale-110 transition-transform">
|
||||||
|
<input
|
||||||
|
type="color"
|
||||||
|
value={color}
|
||||||
|
onChange={(e) => setColor(e.target.value)}
|
||||||
|
className="absolute inset-0 w-[150%] h-[150%] -top-1/4 -left-1/4 cursor-pointer p-0 border-0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Logo Toggle */}
|
||||||
|
<Button
|
||||||
|
variant={withLogo ? 'secondary' : 'outline'}
|
||||||
|
size="sm"
|
||||||
|
onClick={() => setWithLogo(!withLogo)}
|
||||||
|
className="text-xs h-9"
|
||||||
|
title="Toggle Logo"
|
||||||
|
>
|
||||||
|
<ImageIcon className="w-4 h-4 mr-1" />
|
||||||
|
{withLogo ? 'Logo On' : 'Logo'}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
{/* Frame Toggle */}
|
||||||
|
<Button
|
||||||
|
variant={frame !== 'none' ? 'secondary' : 'outline'}
|
||||||
|
size="sm"
|
||||||
|
onClick={() => setFrame(prev => prev === 'none' ? 'scan_me' : prev === 'scan_me' ? 'phone' : 'none')}
|
||||||
|
className="text-xs h-9"
|
||||||
|
title="Change Frame"
|
||||||
|
>
|
||||||
|
<ScanLine className="w-4 h-4 mr-1" />
|
||||||
|
Frame
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => {
|
||||||
|
setUrl('');
|
||||||
|
setColor('#000000');
|
||||||
|
setWithLogo(false);
|
||||||
|
setFrame('none');
|
||||||
|
}}
|
||||||
|
className="text-xs text-gray-500 hover:text-gray-900 h-9 px-2"
|
||||||
|
title="Reset"
|
||||||
|
>
|
||||||
|
<RefreshCw className="w-4 h-4" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-8 space-y-3">
|
||||||
|
<Link href="/create" className="block">
|
||||||
|
<Button className="w-full" size="lg">
|
||||||
|
<Download className="w-4 h-4 mr-2" />
|
||||||
|
Download High-Res
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
<div className="text-center">
|
||||||
|
<p className="text-xs text-gray-500">
|
||||||
|
Unlock gradients, custom shapes & analytics →{' '}
|
||||||
|
<Link href="/signup" className="text-primary-600 hover:underline font-medium">
|
||||||
|
Try Pro Free
|
||||||
|
</Link>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -30,6 +30,7 @@ const tools = [
|
||||||
{ name: 'Email', href: '/tools/email-qr-code', icon: Mail, color: 'text-amber-500', bgColor: 'bg-amber-50' },
|
{ name: 'Email', href: '/tools/email-qr-code', icon: Mail, color: 'text-amber-500', bgColor: 'bg-amber-50' },
|
||||||
{ name: 'SMS', href: '/tools/sms-qr-code', icon: MessageSquare, color: 'text-cyan-500', bgColor: 'bg-cyan-50' },
|
{ name: 'SMS', href: '/tools/sms-qr-code', icon: MessageSquare, color: 'text-cyan-500', bgColor: 'bg-cyan-50' },
|
||||||
{ name: 'Instagram', href: '/tools/instagram-qr-code', icon: Instagram, color: 'text-pink-600', bgColor: 'bg-pink-50' },
|
{ name: 'Instagram', href: '/tools/instagram-qr-code', icon: Instagram, color: 'text-pink-600', bgColor: 'bg-pink-50' },
|
||||||
|
{ name: 'Call', href: '/tools/call-qr-code-generator', icon: Phone, color: 'text-emerald-500', bgColor: 'bg-emerald-50' },
|
||||||
{ name: 'Barcode', href: '/tools/barcode-generator', icon: Barcode, color: 'text-slate-900', bgColor: 'bg-slate-100' },
|
{ name: 'Barcode', href: '/tools/barcode-generator', icon: Barcode, color: 'text-slate-900', bgColor: 'bg-slate-100' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ export function BreadcrumbSchema({ items, showUI = false }: BreadcrumbSchemaProp
|
||||||
export function ToolBreadcrumb({ toolName, toolSlug }: { toolName: string; toolSlug: string }) {
|
export function ToolBreadcrumb({ toolName, toolSlug }: { toolName: string; toolSlug: string }) {
|
||||||
const items: BreadcrumbItem[] = [
|
const items: BreadcrumbItem[] = [
|
||||||
{ name: 'Home', url: 'https://qrmaster.io/' },
|
{ name: 'Home', url: 'https://qrmaster.io/' },
|
||||||
{ name: 'Free QR Code Tools', url: 'https://qrmaster.io/#tools' },
|
{ name: 'Free QR Code Tools', url: 'https://qrmaster.io/tools' },
|
||||||
{ name: toolName, url: `https://qrmaster.io/tools/${toolSlug}` },
|
{ name: toolName, url: `https://qrmaster.io/tools/${toolSlug}` },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
|
|
@ -10,7 +12,7 @@ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||||
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||||
({ className, variant = 'primary', size = 'md', loading, children, disabled, ...props }, ref) => {
|
({ className, variant = 'primary', size = 'md', loading, children, disabled, ...props }, ref) => {
|
||||||
const baseClasses = 'inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed';
|
const baseClasses = 'inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed';
|
||||||
|
|
||||||
const variants = {
|
const variants = {
|
||||||
primary: 'bg-primary-600 text-white hover:bg-primary-700 focus:ring-primary-500',
|
primary: 'bg-primary-600 text-white hover:bg-primary-700 focus:ring-primary-500',
|
||||||
secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200 focus:ring-gray-500',
|
secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200 focus:ring-gray-500',
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,9 @@ export function Footer({ variant = 'marketing', t }: FooterProps) {
|
||||||
|
|
||||||
<li><Link href="/reprint-calculator" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Reprint Cost Calculator</Link></li>
|
<li><Link href="/reprint-calculator" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Reprint Cost Calculator</Link></li>
|
||||||
<li><Link href="/qr-code-tracking" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Our Analytics</Link></li>
|
<li><Link href="/qr-code-tracking" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Our Analytics</Link></li>
|
||||||
|
<li><Link href="/manage-qr-codes" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Manage QR Codes</Link></li>
|
||||||
|
<li><Link href="/custom-qr-code-generator" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Custom QR</Link></li>
|
||||||
|
<li><Link href="/tools/barcode-generator" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Barcode Generator</Link></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@
|
||||||
"price": "€0",
|
"price": "€0",
|
||||||
"period": "forever",
|
"period": "forever",
|
||||||
"features": [
|
"features": [
|
||||||
"8 dynamic QR codes",
|
"3 active dynamic QR codes (8 types available)",
|
||||||
"Unlimited static QR codes",
|
"Unlimited static QR codes",
|
||||||
"Basic scan tracking",
|
"Basic scan tracking",
|
||||||
"Standard QR design templates",
|
"Standard QR design templates",
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ export function getAllIndexableUrls(): string[] {
|
||||||
'url-qr-code', 'vcard-qr-code', 'text-qr-code', 'email-qr-code', 'sms-qr-code',
|
'url-qr-code', 'vcard-qr-code', 'text-qr-code', 'email-qr-code', 'sms-qr-code',
|
||||||
'wifi-qr-code', 'crypto-qr-code', 'event-qr-code', 'facebook-qr-code',
|
'wifi-qr-code', 'crypto-qr-code', 'event-qr-code', 'facebook-qr-code',
|
||||||
'instagram-qr-code', 'twitter-qr-code', 'youtube-qr-code', 'whatsapp-qr-code',
|
'instagram-qr-code', 'twitter-qr-code', 'youtube-qr-code', 'whatsapp-qr-code',
|
||||||
'tiktok-qr-code', 'geolocation-qr-code', 'phone-qr-code', 'paypal-qr-code',
|
'tiktok-qr-code', 'geolocation-qr-code', 'call-qr-code-generator', 'paypal-qr-code',
|
||||||
'zoom-qr-code', 'teams-qr-code',
|
'zoom-qr-code', 'teams-qr-code',
|
||||||
].map(slug => `${baseUrl}/tools/${slug}`);
|
].map(slug => `${baseUrl}/tools/${slug}`);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -243,3 +243,33 @@ export function howToSchema(task: HowToTask) {
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function articleSchema(article: { headline: string; description: string; image: string; datePublished: string; dateModified: string; author: string; url: string }) {
|
||||||
|
return {
|
||||||
|
'@context': 'https://schema.org',
|
||||||
|
'@type': 'Article',
|
||||||
|
'@id': `${article.url}#article`,
|
||||||
|
headline: article.headline,
|
||||||
|
description: article.description,
|
||||||
|
image: article.image,
|
||||||
|
datePublished: article.datePublished,
|
||||||
|
dateModified: article.dateModified,
|
||||||
|
inLanguage: 'en',
|
||||||
|
mainEntityOfPage: article.url,
|
||||||
|
author: {
|
||||||
|
'@type': 'Person',
|
||||||
|
name: article.author,
|
||||||
|
},
|
||||||
|
publisher: {
|
||||||
|
'@type': 'Organization',
|
||||||
|
name: 'QR Master',
|
||||||
|
url: 'https://www.qrmaster.net',
|
||||||
|
logo: {
|
||||||
|
'@type': 'ImageObject',
|
||||||
|
url: 'https://www.qrmaster.net/static/og-image.png',
|
||||||
|
width: 1200,
|
||||||
|
height: 630,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ export function middleware(req: NextRequest) {
|
||||||
'/qr-code-tracking',
|
'/qr-code-tracking',
|
||||||
'/reprint-calculator',
|
'/reprint-calculator',
|
||||||
'/barcode-generator',
|
'/barcode-generator',
|
||||||
|
'/custom-qr-code-generator',
|
||||||
|
'/manage-qr-codes',
|
||||||
];
|
];
|
||||||
|
|
||||||
// Check if path is public
|
// Check if path is public
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ body {
|
||||||
max-width: 100vw;
|
max-width: 100vw;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||||
|
scroll-behavior: smooth;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
|
|
||||||