diff --git a/public/blog/static-vs-dynamic-qr-code.png b/public/blog/static-vs-dynamic-qr-code.png new file mode 100644 index 0000000..d8f796f Binary files /dev/null and b/public/blog/static-vs-dynamic-qr-code.png differ diff --git a/src/app/(main)/(marketing)/MarketingLayout.tsx b/src/app/(main)/(marketing)/MarketingLayout.tsx index c0585a4..dd3ac10 100644 --- a/src/app/(main)/(marketing)/MarketingLayout.tsx +++ b/src/app/(main)/(marketing)/MarketingLayout.tsx @@ -6,11 +6,11 @@ import { usePathname } from 'next/navigation'; import { Button } from '@/components/ui/Button'; import { Footer } from '@/components/ui/Footer'; import en from '@/i18n/en.json'; -import { ChevronDown, BookOpen, Building2, Wifi, Contact, MessageCircle, QrCode, Link2, Type, Mail, MessageSquare, Phone, Calendar, MapPin, Facebook, Instagram, Twitter, Youtube, Music, Bitcoin, CreditCard, Video, Users, Barcode as BarcodeIcon } from 'lucide-react'; +import { ChevronDown, BookOpen, Building2, Wifi, Contact, MessageCircle, QrCode, Link2, Type, Mail, MessageSquare, Phone, Calendar, MapPin, Facebook, Instagram, Twitter, Youtube, Music, Bitcoin, CreditCard, Video, Users, Barcode as BarcodeIcon, Star } from 'lucide-react'; import { cn } from '@/lib/utils'; import { AnimatePresence, motion } from 'framer-motion'; import { allUseCases } from '@/lib/growth-pages'; -import { industryPages } from '@/lib/industry-pages'; +import { industryPages } from '@/lib/industry-pages'; export default function MarketingLayout({ children, @@ -67,6 +67,7 @@ export default function MarketingLayout({ { name: 'Zoom', description: 'Join Zoom meeting', href: '/tools/zoom-qr-code', icon: Video, color: 'text-sky-500', bgColor: 'bg-sky-50' }, { name: 'Teams', description: 'Join Teams meeting', href: '/tools/teams-qr-code', icon: Users, color: 'text-violet-500', bgColor: 'bg-violet-50' }, { name: 'Barcode', description: 'Generate barcodes', href: '/tools/barcode-generator', icon: BarcodeIcon, color: 'text-slate-800', bgColor: 'bg-slate-100' }, + { name: 'Google Review', description: 'Get more reviews', href: '/tools/google-review-qr-code', icon: Star, color: 'text-yellow-500', bgColor: 'bg-yellow-50' }, ]; const resources = [ @@ -105,7 +106,7 @@ export default function MarketingLayout({
  • {uc.title}
  • ))} {/* Industry pages */} - {industryPages.map((ind) => ( + {industryPages.map((ind) => (
  • {ind.title}
  • ))} {/* Tools */} @@ -129,6 +130,7 @@ export default function MarketingLayout({
  • Zoom QR Code
  • Teams QR Code
  • Barcode Generator
  • +
  • Google Review QR Code
  • diff --git a/src/app/(main)/(marketing)/custom-qr-code-generator/page.tsx b/src/app/(main)/(marketing)/custom-qr-code-generator/page.tsx index 96c1233..4e4a7f1 100644 --- a/src/app/(main)/(marketing)/custom-qr-code-generator/page.tsx +++ b/src/app/(main)/(marketing)/custom-qr-code-generator/page.tsx @@ -4,12 +4,12 @@ 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 { GrowthLinksSection } from '@/components/marketing/GrowthLinksSection'; -import { MarketingPageTracker } from '@/components/marketing/MarketingAnalytics'; -import { featuredUseCases } from '@/lib/growth-pages'; +import SeoJsonLd from '@/components/SeoJsonLd'; +import Breadcrumbs, { BreadcrumbItem } from '@/components/Breadcrumbs'; +import { breadcrumbSchema } from '@/lib/schema'; +import { GrowthLinksSection } from '@/components/marketing/GrowthLinksSection'; +import { MarketingPageTracker } from '@/components/marketing/MarketingAnalytics'; +import { featuredUseCases } from '@/lib/growth-pages'; import { Palette, Upload, @@ -290,43 +290,55 @@ export default function CustomQRCodeGeneratorPage() { })), }; - const breadcrumbItems: BreadcrumbItem[] = [ - { name: 'Home', url: '/' }, - { name: 'Custom QR Code Generator', url: '/custom-qr-code-generator' }, - ]; - - const relatedUseCaseLinks = [ - { - href: '/use-cases/flyer-qr-codes', - title: 'Flyer QR Codes', - description: 'Use branded print QR codes when campaign assets need both visual fit and measurable routing.', - ctaLabel: 'Create your flyer QR code', - }, - { - href: featuredUseCases[0].href, - title: featuredUseCases[0].title, - description: featuredUseCases[0].summary, - ctaLabel: featuredUseCases[0].ctaLabel, - }, - { - href: '/use-cases/real-estate-sign-qr-codes', - title: 'Real Estate Sign QR Codes', - description: 'Useful when branded property signage needs a cleaner listing handoff and trackable scan context.', - ctaLabel: 'Create your real estate QR code', - }, - { - href: '/use-cases', - title: 'Explore the use-case hub', - description: 'Browse QR workflows where design, routing, and measurement need to work together.', - ctaLabel: 'Explore QR code use cases', - }, - ]; - - return ( - <> - - -
    + const breadcrumbItems: BreadcrumbItem[] = [ + { name: 'Home', url: '/' }, + { name: 'Custom QR Code Generator', url: '/custom-qr-code-generator' }, + ]; + + const relatedUseCaseLinks = [ + { + href: '/use-cases/flyer-qr-codes', + title: 'Flyer QR Codes', + description: 'Use branded print QR codes when campaign assets need both visual fit and measurable routing.', + ctaLabel: 'Create your flyer QR code', + }, + { + href: featuredUseCases[0].href, + title: featuredUseCases[0].title, + description: featuredUseCases[0].summary, + ctaLabel: featuredUseCases[0].ctaLabel, + }, + { + href: '/use-cases/real-estate-sign-qr-codes', + title: 'Real Estate Sign QR Codes', + description: 'Useful when branded property signage needs a cleaner listing handoff and trackable scan context.', + ctaLabel: 'Create your real estate QR code', + }, + { + href: '/dynamic-qr-code-generator', + title: 'Dynamic QR Code Generator', + description: 'Add tracking and updatable destinations to your branded QR codes.', + ctaLabel: 'Create dynamic QR', + }, + { + href: '/tools/vcard-qr-code', + title: 'vCard QR Code Generator', + description: 'Turn your brand identity into a scannable digital business card.', + ctaLabel: 'Create vCard QR', + }, + { + href: '/use-cases', + title: 'Explore the use-case hub', + description: 'Browse QR workflows where design, routing, and measurement need to work together.', + ctaLabel: 'Explore QR code use cases', + }, + ]; + + return ( + <> + + +
    {/* Hero Section */}
    @@ -652,20 +664,20 @@ export default function CustomQRCodeGeneratorPage() {
    - - - - - - {/* Final CTA */} -
    + +
    + + + + {/* Final CTA */} +

    Start Creating Branded QR Codes Today diff --git a/src/app/(main)/(marketing)/dynamic-qr-code-generator/page.tsx b/src/app/(main)/(marketing)/dynamic-qr-code-generator/page.tsx index e93dbec..5916cd4 100644 --- a/src/app/(main)/(marketing)/dynamic-qr-code-generator/page.tsx +++ b/src/app/(main)/(marketing)/dynamic-qr-code-generator/page.tsx @@ -273,6 +273,20 @@ const relatedUseCaseLinks = [ description: featuredUseCases[1].summary, ctaLabel: featuredUseCases[1].ctaLabel, }, + { + href: '/qr-code-tracking', + title: 'Track Every QR Code Scan', + description: + 'See device, time, and location context for every scan. Understand which placements drive real activity.', + ctaLabel: 'Track your QR scans', + }, + { + href: '/reprint-calculator', + title: 'QR Code Reprint Cost Calculator', + description: + 'Calculate how much static QR reprints cost vs one active dynamic QR code.', + ctaLabel: 'Calculate reprint savings', + }, { href: '/use-cases', title: 'Explore the use-case hub', diff --git a/src/app/(main)/(marketing)/qr-code-analytics/page.tsx b/src/app/(main)/(marketing)/qr-code-analytics/page.tsx index ae27b27..1cd860b 100644 --- a/src/app/(main)/(marketing)/qr-code-analytics/page.tsx +++ b/src/app/(main)/(marketing)/qr-code-analytics/page.tsx @@ -4,6 +4,7 @@ import { buildUseCaseMetadata, UseCasePageTemplate, } from "@/components/marketing/UseCasePageTemplate"; +import { GrowthLinksSection } from "@/components/marketing/GrowthLinksSection"; export const metadata: Metadata = buildUseCaseMetadata({ title: "QR Code Analytics", @@ -38,6 +39,7 @@ const softwareSchema = { export default function QRCodeAnalyticsPage() { return ( + <> + + ); } diff --git a/src/app/(main)/(marketing)/qr-code-print-size-guide/page.tsx b/src/app/(main)/(marketing)/qr-code-print-size-guide/page.tsx new file mode 100644 index 0000000..fdb383e --- /dev/null +++ b/src/app/(main)/(marketing)/qr-code-print-size-guide/page.tsx @@ -0,0 +1,321 @@ +import React from 'react'; +import type { Metadata } from 'next'; +import SeoJsonLd from '@/components/SeoJsonLd'; +import { GrowthLinksSection } from '@/components/marketing/GrowthLinksSection'; +import { breadcrumbSchema } from '@/lib/schema'; +import Breadcrumbs from '@/components/Breadcrumbs'; + +export const metadata: Metadata = { + title: 'QR Code Print Size Guide: Minimum Sizes for Every Surface | QR Master', + description: 'The minimum QR code size for print depends on scan distance. This guide gives you exact dimensions for business cards, flyers, posters, and billboards.', + keywords: ['minimum qr code size', 'qr code print size', 'qr code size for print', 'how big should a qr code be', 'qr code dimensions'], + alternates: { + canonical: 'https://www.qrmaster.net/qr-code-print-size-guide', + }, + openGraph: { + title: 'QR Code Print Size Guide | QR Master', + description: 'Exact QR code dimensions for every print surface — from business cards to billboards.', + type: 'article', + url: 'https://www.qrmaster.net/qr-code-print-size-guide', + }, + robots: { + index: true, + follow: true, + }, +}; + +const breadcrumbs = [ + { name: 'Home', url: '/' }, + { name: 'QR Code Print Size Guide', url: '/qr-code-print-size-guide' }, +]; + +const articleSchema = { + '@context': 'https://schema.org', + '@type': 'Article', + '@id': 'https://www.qrmaster.net/qr-code-print-size-guide#article', + headline: 'QR Code Print Size Guide: Minimum Sizes for Every Surface', + description: 'The minimum QR code size for print depends on scan distance. This guide gives you exact dimensions for business cards, flyers, posters, and billboards.', + author: { + '@type': 'Organization', + name: 'QR Master', + url: 'https://www.qrmaster.net', + }, + publisher: { + '@type': 'Organization', + name: 'QR Master', + url: 'https://www.qrmaster.net', + }, + datePublished: '2026-04-07', + dateModified: '2026-04-07', + mainEntityOfPage: 'https://www.qrmaster.net/qr-code-print-size-guide', +}; + +const faqSchema = { + '@context': 'https://schema.org', + '@type': 'FAQPage', + mainEntity: [ + { + '@type': 'Question', + name: 'What is the minimum size for a QR code to be scannable?', + acceptedAnswer: { + '@type': 'Answer', + text: 'The minimum recommended size is 2 × 2 cm (0.8 × 0.8 in) for QR codes scanned at very close range (under 10 cm), such as on business cards. For most print materials scanned at arm\'s length (30–40 cm), use at least 3 × 3 cm.', + }, + }, + { + '@type': 'Question', + name: 'What DPI should I use for printing a QR code?', + acceptedAnswer: { + '@type': 'Answer', + text: 'For print, export your QR code at a minimum of 300 DPI. For large-format printing (posters, banners), use the vector SVG format instead of PNG — SVG scales to any size without quality loss.', + }, + }, + { + '@type': 'Question', + name: 'How big should a QR code be on a poster?', + acceptedAnswer: { + '@type': 'Answer', + text: 'For an A2 poster (420 × 594 mm) viewed at 1–2 metres, use a QR code that is at least 8 × 8 cm. Larger is always better — a 10 × 10 cm code scans reliably from 2–3 metres away.', + }, + }, + { + '@type': 'Question', + name: 'How big should a QR code be on a business card?', + acceptedAnswer: { + '@type': 'Answer', + text: 'On a standard business card (85 × 55 mm), a QR code of 2 × 2 cm to 2.5 × 2.5 cm works reliably when held at normal reading distance (15–20 cm).', + }, + }, + { + '@type': 'Question', + name: 'Does adding a logo to a QR code affect scannability?', + acceptedAnswer: { + '@type': 'Answer', + text: 'Only if the logo covers more than about 30% of the QR code area. QR codes have built-in error correction. At "Q" (25%) or "H" (30%) error correction level, a logo is fine. Always test scan after adding a logo.', + }, + }, + ], +}; + +const sizeData = [ + { surface: 'Business Card', scanDistance: '15–20 cm', minSize: '2 × 2 cm', recommended: '2.5 × 2.5 cm', dpi: '300 DPI PNG', format: 'PNG or SVG' }, + { surface: 'Flyer / Leaflet', scanDistance: '20–30 cm', minSize: '3 × 3 cm', recommended: '4 × 4 cm', dpi: '300 DPI PNG', format: 'PNG or SVG' }, + { surface: 'A4 Poster', scanDistance: '30–60 cm', minSize: '5 × 5 cm', recommended: '7 × 7 cm', dpi: '300 DPI PNG', format: 'SVG recommended' }, + { surface: 'A2 / A1 Poster', scanDistance: '1–2 m', minSize: '8 × 8 cm', recommended: '10 × 10 cm', dpi: '300 DPI', format: 'SVG required' }, + { surface: 'Window / Banner', scanDistance: '1–3 m', minSize: '10 × 10 cm', recommended: '15 × 15 cm', dpi: 'Vector only', format: 'SVG required' }, + { surface: 'Billboard', scanDistance: '3–10 m', minSize: '20 × 20 cm', recommended: '30 × 30 cm', dpi: 'Vector only', format: 'SVG required' }, +]; + +export default function QRCodePrintSizeGuidePage() { + return ( + <> + + +
    + + {/* HERO */} +
    +
    + +
    + Print Guide +
    +

    + QR Code Print Size Guide +

    +

    + The right QR code size depends on one thing: how far away will the scanner be? + This guide gives you exact minimum dimensions for every print surface. +

    +
    +

    Quick Rule of Thumb

    +

    + QR code width = scan distance ÷ 10. Example: scanning from 30 cm → minimum 3 cm wide. +

    +
    +
    +
    + + {/* SIZE TABLE */} +
    +
    +

    + Recommended Size by Print Surface and Scan Distance +

    + +
    + + + + + + + + + + + + {sizeData.map((row, i) => ( + + + + + + + + ))} + +
    SurfaceScan DistanceMinimum SizeRecommendedFormat
    {row.surface}{row.scanDistance}{row.minSize}{row.recommended}{row.format}
    +
    +

    + Sizes are for QR codes with standard black-on-white contrast at error correction level Q or H. Reduce minimum sizes by 20% only in ideal lighting conditions. +

    +
    +
    + + {/* DPI & FORMAT GUIDE */} +
    +
    +

    DPI and Format Requirements

    + +
    +
    +
    + PNG +
    +

    PNG for Small Print

    +

    + Use PNG at 300 DPI minimum for business cards, flyers, and small posters. Export at 10× your target print size in pixels (e.g. 3 cm at 300 DPI = 354 px). +

    +
    + +
    +
    + SVG +
    +

    SVG for Everything Larger

    +

    + SVG is a vector format — it scales to any size without quality loss. Use SVG for all A2+ posters, banners, and billboards. QR Master exports SVG directly from the generator. +

    +
    + +
    +
    + ECL +
    +

    Error Correction Level

    +

    + Use Level Q (25% recovery) or Level H (30% recovery) for print — especially if you add a logo. Higher error correction means more modules and a slightly larger minimum size. +

    +
    +
    +
    +
    + + {/* PRINT CHECKLIST */} +
    +
    +

    Print QR Code Checklist

    +
      + {[ + 'QR code is at least the minimum size for the intended scan distance', + 'High contrast between QR modules and background (black on white preferred)', + 'Quiet zone (white border) of at least 4 module widths on all sides', + 'Exported as SVG for large format, PNG at 300+ DPI for small format', + 'Scanned from target distance before sending to print', + 'Error correction set to Q or H if a logo is embedded', + 'Dynamic QR code used if the destination URL might change', + ].map((item) => ( +
    • + + + + + + {item} +
    • + ))} +
    +
    +
    + + + + {/* FAQ */} +
    +
    +

    + Frequently Asked Questions +

    + +
    + {[ + { + question: 'What is the minimum size for a QR code to be scannable?', + answer: 'The absolute minimum is 2 × 2 cm for scanning at very close range (business cards, held 15 cm away). For most materials, use at least 3 × 3 cm. The general rule: minimum width = scan distance ÷ 10.', + }, + { + question: 'What DPI should I use for printing a QR code?', + answer: 'Use 300 DPI minimum for all print. For large format (posters, banners, billboards), always use SVG — it is vector-based and scales to any size without quality loss.', + }, + { + question: 'How big should a QR code be on a poster?', + answer: 'For an A2 poster viewed at 1–2 metres, use at least 8 × 8 cm. For A1 posters viewed from further away, 10 × 10 cm is recommended.', + }, + { + question: 'How big should a QR code be on a business card?', + answer: 'On a standard business card (85 × 55 mm), a 2 × 2 cm to 2.5 × 2.5 cm QR code works reliably when scanned at normal reading distance.', + }, + { + question: 'Does adding a logo affect QR code scannability?', + answer: 'Only if the logo covers more than ~30% of the QR area. Use error correction level Q or H when adding logos. Always test scan before printing at scale.', + }, + ].map((item) => ( +
    + + {item.question} + + + + + + +
    + {item.answer} +
    +
    + ))} +
    +
    +
    + +
    + + ); +} diff --git a/src/app/(main)/(marketing)/qr-code-tracking/page.tsx b/src/app/(main)/(marketing)/qr-code-tracking/page.tsx index 12a5b99..7b20672 100644 --- a/src/app/(main)/(marketing)/qr-code-tracking/page.tsx +++ b/src/app/(main)/(marketing)/qr-code-tracking/page.tsx @@ -241,6 +241,20 @@ const relatedUseCaseLinks = [ 'Tie printed discount placements to measurable scans so you can compare promotion performance.', ctaLabel: 'Create your coupon QR code', }, + { + href: '/qr-code-analytics', + title: 'QR Code Analytics Dashboard', + description: + 'Go deeper into placement-level reporting and offline campaign attribution.', + ctaLabel: 'Explore QR analytics', + }, + { + href: '/reprint-calculator', + title: 'QR Code Reprint Cost Calculator', + description: + 'See how much dynamic QR codes save vs reprinting static codes each campaign.', + ctaLabel: 'Calculate reprint savings', + }, { href: '/use-cases', title: 'Explore the use-case hub', diff --git a/src/app/(main)/(marketing)/reprint-calculator/page.tsx b/src/app/(main)/(marketing)/reprint-calculator/page.tsx index 4729074..18c4ef1 100644 --- a/src/app/(main)/(marketing)/reprint-calculator/page.tsx +++ b/src/app/(main)/(marketing)/reprint-calculator/page.tsx @@ -2,6 +2,9 @@ import React from 'react'; import type { Metadata } from 'next'; import ReprintSavingsCalculator from '@/components/marketing/ReprintSavingsCalculator'; import { ArrowDown, Check, ShieldCheck, Zap } from 'lucide-react'; +import SeoJsonLd from '@/components/SeoJsonLd'; +import { GrowthLinksSection } from '@/components/marketing/GrowthLinksSection'; +import { breadcrumbSchema } from '@/lib/schema'; export const metadata: Metadata = { title: 'Reprint Cost Calculator | QR Master', @@ -30,9 +33,58 @@ export const metadata: Metadata = { }, }; +const softwareSchema = { + '@context': 'https://schema.org', + '@type': 'WebApplication', + '@id': 'https://www.qrmaster.net/reprint-calculator#app', + name: 'QR Code Reprint Cost Calculator', + applicationCategory: 'BusinessApplication', + operatingSystem: 'Web Browser', + offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' }, + description: 'Calculate the cost of reprinting static QR codes vs switching to dynamic QR codes that never need reprinting.', +}; + +const howToSchema = { + '@context': 'https://schema.org', + '@type': 'HowTo', + name: 'How to calculate QR code reprint costs', + step: [ + { '@type': 'HowToStep', position: 1, name: 'Enter print run size', text: 'Enter how many QR codes you print per campaign.' }, + { '@type': 'HowToStep', position: 2, name: 'Enter reprint cost', text: 'Enter your cost per reprint campaign.' }, + { '@type': 'HowToStep', position: 3, name: 'See annual savings', text: 'The calculator shows how much dynamic QR codes save annually.' }, + ], +}; + +const breadcrumbs = [ + { name: 'Home', url: '/' }, + { name: 'Reprint Calculator', url: '/reprint-calculator' }, +]; + +const growthLinks = [ + { + href: '/dynamic-qr-code-generator', + title: 'Dynamic QR Code Generator', + description: 'Create QR codes you can update after printing. Change the destination without reprinting a single flyer.', + ctaLabel: 'Create dynamic QR code', + }, + { + href: '/qr-code-tracking', + title: 'QR Code Tracking', + description: 'See device, time, and location context for every scan. Know which placements drive real activity.', + ctaLabel: 'Track your QR scans', + }, + { + href: '/pricing', + title: 'Compare Plans', + description: 'One dynamic QR subscription costs less than a single batch of reprints. See the plan that fits your volume.', + ctaLabel: 'Compare plans', + }, +]; + export default function ReprintCalculatorPage() { return ( <> + {/* Hero Section */}
    @@ -112,6 +164,15 @@ export default function ReprintCalculatorPage() {

    + + ); } diff --git a/src/app/(main)/(marketing)/tools/google-review-qr-code/GoogleReviewGenerator.tsx b/src/app/(main)/(marketing)/tools/google-review-qr-code/GoogleReviewGenerator.tsx new file mode 100644 index 0000000..bcf4e6e --- /dev/null +++ b/src/app/(main)/(marketing)/tools/google-review-qr-code/GoogleReviewGenerator.tsx @@ -0,0 +1,213 @@ +'use client'; + +import React, { useState, useRef } from 'react'; +import { QRCodeSVG } from 'qrcode.react'; +import { toPng } from 'html-to-image'; +import { Star, Download, AlertCircle } from 'lucide-react'; +import { Button } from '@/components/ui/Button'; +import { Input } from '@/components/ui/Input'; + +const QR_COLORS = [ + { name: 'Google Blue', value: '#1A73E8' }, + { name: 'Classic Black', value: '#000000' }, + { name: 'Indigo', value: '#4F46E5' }, + { name: 'Emerald', value: '#10B981' }, + { name: 'Rose', value: '#F43F5E' }, + { name: 'Violet', value: '#7C3AED' }, +]; + +const FRAME_OPTIONS = [ + { id: 'none', label: 'No Frame' }, + { id: 'review', label: 'Leave a Review' }, + { id: 'scanme', label: 'Scan Me' }, + { id: 'feedback', label: 'Share Feedback' }, +]; + +function isValidGoogleReviewLink(url: string): boolean { + try { + const parsed = new URL(url); + return ( + parsed.hostname.includes('google.com') || + parsed.hostname.includes('g.page') || + parsed.hostname.includes('maps.app.goo.gl') + ); + } catch { + return false; + } +} + +export default function GoogleReviewGenerator() { + const [reviewUrl, setReviewUrl] = useState(''); + const [qrColor, setQrColor] = useState('#1A73E8'); + const [frameType, setFrameType] = useState('review'); + const [error, setError] = useState(''); + + const qrRef = useRef(null); + + const handleUrlChange = (value: string) => { + setReviewUrl(value); + if (value && !isValidGoogleReviewLink(value)) { + setError('Please enter a valid Google Review link (google.com, g.page, or maps.app.goo.gl)'); + } else { + setError(''); + } + }; + + const handleDownload = async (format: 'png' | 'svg') => { + if (!qrRef.current) return; + try { + if (format === 'png') { + const dataUrl = await toPng(qrRef.current, { cacheBust: true, pixelRatio: 3 }); + const link = document.createElement('a'); + link.download = 'google-review-qr-code.png'; + link.href = dataUrl; + link.click(); + } else { + const svgData = qrRef.current.querySelector('svg')?.outerHTML; + if (svgData) { + const blob = new Blob([svgData], { type: 'image/svg+xml;charset=utf-8' }); + const url = URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = url; + link.download = 'google-review-qr-code.svg'; + link.click(); + } + } + } catch (err) { + console.error('Download failed', err); + } + }; + + const frameLabel = FRAME_OPTIONS.find(f => f.id === frameType && f.id !== 'none')?.label ?? null; + const isReady = reviewUrl && !error && isValidGoogleReviewLink(reviewUrl); + + return ( +
    +
    +
    + + {/* LEFT: Input */} +
    + +
    +

    + + Your Google Review Link +

    + +
    + handleUrlChange(e.target.value)} + className="w-full font-mono text-sm" + /> + {error && ( +
    + + {error} +
    + )} + {!reviewUrl && ( +

    + Go to Google Maps → find your business → Share → Copy link +

    + )} +
    +
    + + {/* Color Picker */} +
    +

    QR Color

    +
    + {QR_COLORS.map((color) => ( +
    +
    + + {/* Frame */} +
    +

    Frame Label

    +
    + {FRAME_OPTIONS.map((frame) => ( + + ))} +
    +
    + + {/* Download Buttons */} +
    + + +
    +
    + + {/* RIGHT: Preview */} +
    +

    Preview

    + +
    + + {frameLabel && ( +
    + {frameLabel} +
    + )} +
    + + {!isReady && ( +

    + Enter your Google Review link to generate your QR code +

    + )} +
    +
    +
    +
    + ); +} diff --git a/src/app/(main)/(marketing)/tools/google-review-qr-code/page.tsx b/src/app/(main)/(marketing)/tools/google-review-qr-code/page.tsx new file mode 100644 index 0000000..231bfe0 --- /dev/null +++ b/src/app/(main)/(marketing)/tools/google-review-qr-code/page.tsx @@ -0,0 +1,366 @@ +import React from 'react'; +import type { Metadata } from 'next'; +import GoogleReviewGenerator from './GoogleReviewGenerator'; +import { Star, MapPin, Search, Share2 } from 'lucide-react'; +import { QRCodeSVG } from 'qrcode.react'; +import { ToolBreadcrumb } from '@/components/seo/BreadcrumbSchema'; +import { RelatedTools } from '@/components/marketing/RelatedTools'; +import { GrowthLinksSection } from '@/components/marketing/GrowthLinksSection'; +import { generateSoftwareAppSchema } from '@/lib/schema-utils'; + +export const metadata: Metadata = { + title: { + absolute: 'Google Review QR Code Generator — Free | QR Master', + }, + description: 'Create a QR code for your Google Reviews in seconds. Customers scan once and land directly on your review form. Free, no signup required.', + keywords: ['qr code for google reviews', 'qr code generator for google reviews', 'google review qr code', 'google maps review qr code', 'get more google reviews'], + alternates: { + canonical: 'https://www.qrmaster.net/tools/google-review-qr-code', + }, + openGraph: { + title: 'Google Review QR Code Generator — Free | QR Master', + description: 'Create a QR code that takes customers directly to your Google review form. More reviews, less friction.', + type: 'website', + url: 'https://www.qrmaster.net/tools/google-review-qr-code', + }, + twitter: { + card: 'summary_large_image', + title: 'Google Review QR Code Generator — Free', + description: 'Create a QR code that takes customers directly to your Google review form.', + }, + robots: { + index: true, + follow: true, + }, +}; + +const jsonLd = { + '@context': 'https://schema.org', + '@graph': [ + generateSoftwareAppSchema( + 'Google Review QR Code Generator', + 'Generate a QR code that links directly to your Google review form. Customers scan once and can leave a review immediately.', + '/og-image.png' + ), + { + '@type': 'HowTo', + name: 'How to Create a Google Review QR Code', + description: 'Generate a QR code that sends customers directly to your Google review form.', + step: [ + { + '@type': 'HowToStep', + position: 1, + name: 'Find your Google Review link', + text: 'Open Google Maps, search for your business, click Share → Copy link. Or use Google Business Profile → Get more reviews.', + }, + { + '@type': 'HowToStep', + position: 2, + name: 'Paste the link into the generator', + text: 'Paste your Google review URL into the field above. The generator accepts g.page, google.com, and maps.app.goo.gl links.', + }, + { + '@type': 'HowToStep', + position: 3, + name: 'Customize and download', + text: 'Choose a color and frame label (e.g. "Leave a Review"), then download as PNG or SVG.', + }, + { + '@type': 'HowToStep', + position: 4, + name: 'Display the QR code', + text: 'Print the code on receipts, table cards, packaging, or your window. Customers scan once to review.', + }, + ], + totalTime: 'PT60S', + }, + { + '@type': 'FAQPage', + mainEntity: [ + { + '@type': 'Question', + name: 'How do I find my Google Review link?', + acceptedAnswer: { + '@type': 'Answer', + text: 'Open Google Maps → search for your business → click Share → Copy link. Alternatively, go to your Google Business Profile dashboard → click "Get more reviews" — this gives you a direct review shortlink.', + }, + }, + { + '@type': 'Question', + name: 'Does this Google Review QR code expire?', + acceptedAnswer: { + '@type': 'Answer', + text: 'No. This is a static QR code that directly encodes your Google review URL. It will work as long as your Google Business Profile is active.', + }, + }, + { + '@type': 'Question', + name: 'Can I track how many people scanned the QR code?', + acceptedAnswer: { + '@type': 'Answer', + text: 'Not with a static QR code. If you need scan analytics (device, location, time), create a dynamic QR code with tracking through QR Master.', + }, + }, + { + '@type': 'Question', + name: 'What happens when a customer scans the QR code?', + acceptedAnswer: { + '@type': 'Answer', + text: 'They are taken directly to your Google review form. If they are logged into a Google account on their phone, they can leave a review immediately with no extra steps.', + }, + }, + { + '@type': 'Question', + name: 'Where should I display the Google Review QR code?', + acceptedAnswer: { + '@type': 'Answer', + text: 'Best placements: receipts, table tent cards (restaurants), checkout counters, packaging inserts, and your shop window. The moment after a positive experience is the best time to ask for a review.', + }, + }, + ], + }, + { + '@type': 'BreadcrumbList', + itemListElement: [ + { '@type': 'ListItem', position: 1, name: 'Home', item: 'https://www.qrmaster.net' }, + { '@type': 'ListItem', position: 2, name: 'QR Code Tools', item: 'https://www.qrmaster.net/tools' }, + { '@type': 'ListItem', position: 3, name: 'Google Review QR Code Generator', item: 'https://www.qrmaster.net/tools/google-review-qr-code' }, + ], + }, + ], +}; + +export default function GoogleReviewQRCodePage() { + return ( + <> +