SEO/AEO
This commit is contained in:
@@ -1,157 +1,324 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { useParams } from 'next/navigation';
|
||||
import type { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import { notFound } from 'next/navigation';
|
||||
import SeoJsonLd from '@/components/SeoJsonLd';
|
||||
import Breadcrumbs, { BreadcrumbItem } from '@/components/Breadcrumbs';
|
||||
import { blogPostingSchema, breadcrumbSchema, howToSchema } from '@/lib/schema';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { Badge } from '@/components/ui/Badge';
|
||||
|
||||
const blogContent = {
|
||||
'qr-codes-im-restaurant': {
|
||||
title: 'QR-Codes im Restaurant: Die digitale Revolution der Speisekarte',
|
||||
date: '2024-01-15',
|
||||
readTime: '5 Min',
|
||||
category: 'Gastronomie',
|
||||
content: `
|
||||
<p>Die Gastronomie hat sich in den letzten Jahren stark digitalisiert, und QR-Codes spielen dabei eine zentrale Rolle. Von kontaktlosen Speisekarten bis hin zu digitalen Zahlungssystemen – QR-Codes revolutionieren die Art und Weise, wie Restaurants mit ihren Gästen interagieren.</p>
|
||||
|
||||
<h2>Vorteile für Restaurants</h2>
|
||||
<ul>
|
||||
<li>Kostenersparnis durch digitale Speisekarten</li>
|
||||
<li>Einfache Aktualisierung von Preisen und Angeboten</li>
|
||||
<li>Hygienische, kontaktlose Lösung</li>
|
||||
<li>Mehrsprachige Menüs ohne zusätzliche Druckkosten</li>
|
||||
</ul>
|
||||
|
||||
<h2>Vorteile für Gäste</h2>
|
||||
<ul>
|
||||
<li>Schneller Zugriff auf aktuelle Informationen</li>
|
||||
<li>Detaillierte Produktbeschreibungen und Allergeninformationen</li>
|
||||
<li>Einfache Bestellung und Bezahlung</li>
|
||||
<li>Personalisierte Empfehlungen</li>
|
||||
</ul>
|
||||
|
||||
<p>Die Implementierung von QR-Codes in Ihrem Restaurant ist einfacher als Sie denken. Mit QR Master können Sie in wenigen Minuten professionelle QR-Codes erstellen, die perfekt zu Ihrem Branding passen.</p>
|
||||
`,
|
||||
},
|
||||
'dynamische-vs-statische-qr-codes': {
|
||||
title: 'Dynamische vs. Statische QR-Codes: Was ist der Unterschied?',
|
||||
date: '2024-01-10',
|
||||
readTime: '3 Min',
|
||||
category: 'Grundlagen',
|
||||
content: `
|
||||
<p>Bei der Erstellung von QR-Codes stehen Sie vor der Wahl zwischen statischen und dynamischen Codes. Beide haben ihre Vor- und Nachteile, und die richtige Wahl hängt von Ihrem spezifischen Anwendungsfall ab.</p>
|
||||
|
||||
<h2>Statische QR-Codes</h2>
|
||||
<p>Statische QR-Codes enthalten die Informationen direkt im Code selbst. Einmal erstellt, können sie nicht mehr geändert werden.</p>
|
||||
<ul>
|
||||
<li>Kostenlos und unbegrenzt nutzbar</li>
|
||||
<li>Funktionieren für immer ohne Server</li>
|
||||
<li>Ideal für permanente Informationen</li>
|
||||
<li>Keine Tracking-Möglichkeiten</li>
|
||||
</ul>
|
||||
|
||||
<h2>Dynamische QR-Codes</h2>
|
||||
<p>Dynamische QR-Codes verweisen auf eine URL, die Sie jederzeit ändern können.</p>
|
||||
<ul>
|
||||
<li>Inhalt kann nachträglich geändert werden</li>
|
||||
<li>Detaillierte Scan-Statistiken</li>
|
||||
<li>Kürzere, sauberere QR-Codes</li>
|
||||
<li>Perfekt für Marketing-Kampagnen</li>
|
||||
</ul>
|
||||
|
||||
<p>Mit QR Master können Sie beide Arten von QR-Codes erstellen und verwalten. Unsere Plattform bietet Ihnen die Flexibilität, die Sie für Ihre Projekte benötigen.</p>
|
||||
`,
|
||||
},
|
||||
'qr-code-marketing-strategien': {
|
||||
title: 'QR-Code Marketing-Strategien für 2024',
|
||||
date: '2024-01-05',
|
||||
readTime: '7 Min',
|
||||
category: 'Marketing',
|
||||
content: `
|
||||
<p>QR-Codes sind zu einem unverzichtbaren Werkzeug im modernen Marketing geworden. Hier sind die effektivsten Strategien für 2024.</p>
|
||||
|
||||
<h2>1. Personalisierte Kundenerlebnisse</h2>
|
||||
<p>Nutzen Sie dynamische QR-Codes, um personalisierte Landingpages basierend auf Standort, Zeit oder Kundenverhalten zu erstellen.</p>
|
||||
|
||||
<h2>2. Social Media Integration</h2>
|
||||
<p>Verbinden Sie QR-Codes mit Ihren Social-Media-Kampagnen für nahtlose Cross-Channel-Erlebnisse.</p>
|
||||
|
||||
<h2>3. Event-Marketing</h2>
|
||||
<p>Von Tickets bis zu Networking – QR-Codes machen Events interaktiver und messbar.</p>
|
||||
|
||||
<h2>4. Loyalty-Programme</h2>
|
||||
<p>Digitale Treuekarten und Rabattaktionen lassen sich perfekt mit QR-Codes umsetzen.</p>
|
||||
|
||||
<h2>5. Analytics und Optimierung</h2>
|
||||
<p>Nutzen Sie die Tracking-Funktionen, um Ihre Kampagnen kontinuierlich zu verbessern.</p>
|
||||
|
||||
<p>Mit QR Master haben Sie alle Tools, die Sie für erfolgreiches QR-Code-Marketing benötigen. Starten Sie noch heute mit Ihrer ersten Kampagne!</p>
|
||||
`,
|
||||
interface BlogPostData {
|
||||
slug: string;
|
||||
title: string;
|
||||
excerpt: string;
|
||||
date: string;
|
||||
datePublished: string;
|
||||
dateModified: string;
|
||||
readTime: string;
|
||||
category: string;
|
||||
image: string;
|
||||
imageAlt: string;
|
||||
author: string;
|
||||
authorUrl: string;
|
||||
answer?: string;
|
||||
howTo?: any;
|
||||
content: string;
|
||||
}
|
||||
|
||||
const blogPosts: Record<string, BlogPostData> = {
|
||||
'qr-code-analytics': {
|
||||
slug: 'qr-code-analytics',
|
||||
title: 'QR Code Analytics: Track, Measure & Optimize',
|
||||
excerpt: 'Master scan analytics, campaign tracking & dashboard insights to maximize QR ROI with dynamic codes.',
|
||||
date: 'October 16, 2025',
|
||||
datePublished: '2025-10-16T09:00:00Z',
|
||||
dateModified: '2025-10-16T09:00:00Z',
|
||||
readTime: '8 Min',
|
||||
category: 'Analytics',
|
||||
image: 'https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=1200&q=80',
|
||||
imageAlt: 'QR code analytics dashboard showing real-time scan metrics and campaign performance data',
|
||||
author: 'QR Master Team',
|
||||
authorUrl: 'https://www.qrmaster.com/about',
|
||||
answer: 'QR code analytics empowers marketers to track scan rates, user behavior, and campaign ROI through real-time dashboards, enabling data-driven optimization of dynamic QR codes and branded marketing campaigns.',
|
||||
howTo: {
|
||||
name: 'How to Track QR Code Scans',
|
||||
description: 'Step-by-step guide to setting up and monitoring QR code analytics',
|
||||
totalTime: 'PT10M',
|
||||
steps: [
|
||||
{
|
||||
name: 'Create a Dynamic QR Code',
|
||||
text: 'Log into your QR Master dashboard and select "Create Dynamic QR Code". Enter your destination URL and customize design options.',
|
||||
url: 'https://www.qrmaster.com/create',
|
||||
},
|
||||
{
|
||||
name: 'Enable UTM Tracking',
|
||||
text: 'Add UTM parameters (source, medium, campaign) to track the QR code in Google Analytics and marketing platforms.',
|
||||
},
|
||||
{
|
||||
name: 'Access Analytics Dashboard',
|
||||
text: 'Navigate to Dashboard → Analytics to view real-time scan data, geographic distribution, and device breakdowns.',
|
||||
url: 'https://www.qrmaster.com/analytics',
|
||||
},
|
||||
],
|
||||
},
|
||||
content: `<div class="blog-content">
|
||||
<h2>What Are Scan Analytics?</h2>
|
||||
<p>Scan analytics provide comprehensive insights into how users interact with your QR codes. Our advanced dashboard tracks scan analytics including geographic location, device types, scan timestamps, and user engagement patterns. For marketers running dynamic QR code campaigns, these insights are essential for understanding campaign tracking performance and optimizing conversion rates.</p>
|
||||
<p>With branded QR codes deployed across print materials, event tickets, and business cards, scan analytics reveal which channels drive the highest engagement. Security features ensure all data collection is GDPR-compliant, protecting user privacy while delivering actionable campaign tracking insights.</p>
|
||||
|
||||
<h2>How to Set Up QR Code Analytics</h2>
|
||||
<h3>Step 1: Create a Dynamic QR Code</h3>
|
||||
<p>Start by generating a dynamic QR code in your QR Master dashboard. Unlike static codes, dynamic QR codes allow you to update destination URLs and track every scan through our analytics platform.</p>
|
||||
|
||||
<h3>Step 2: Enable Campaign Tracking</h3>
|
||||
<p>Configure UTM parameters for your QR codes to integrate with Google Analytics and marketing automation platforms. UTM tracking allows you to attribute conversions, measure ROI, and segment campaign performance by source, medium, and campaign name.</p>
|
||||
|
||||
<h3>Step 3: Access Your Analytics Dashboard</h3>
|
||||
<p>Navigate to the scan analytics dashboard to view real-time reports. Monitor scan rates, geographic distribution, device breakdowns, and time-series data. Set up automated reports to track campaign tracking metrics over time.</p>
|
||||
|
||||
<h3>Step 4: Optimize Based on Insights</h3>
|
||||
<p>Use scan analytics to identify high-performing campaigns and optimize underperforming ones. A/B test different branded QR designs, placement strategies, and call-to-action messaging to maximize engagement and conversion rates.</p>
|
||||
|
||||
<h2>Key Metrics in QR Code Analytics</h2>
|
||||
<h3>Scan Rates and Volume</h3>
|
||||
<p>Track total scans, unique scans, and scan velocity. Scan rates reveal campaign momentum and help identify viral growth patterns. Compare scan volumes across different branded QR variations to determine which designs perform best.</p>
|
||||
|
||||
<h3>Geographic Distribution</h3>
|
||||
<p>Understand where your audience is scanning from. Geographic analytics support localized marketing strategies and event tracking for conferences, trade shows, and retail activations.</p>
|
||||
|
||||
<h3>Device and Browser Analytics</h3>
|
||||
<p>Know whether users scan from iOS or Android devices, which browsers they use, and screen resolutions. This data informs mobile optimization strategies and ensures your landing pages deliver seamless experiences across all devices.</p>
|
||||
|
||||
<h3>Time-Based Patterns</h3>
|
||||
<p>Identify peak scanning hours, days of the week, and seasonal trends. Time-based analytics optimize campaign timing for email blasts, social media posts, and print QR deployments.</p>
|
||||
|
||||
<h3>Conversion Tracking</h3>
|
||||
<p>Measure downstream actions after the scan—form submissions, purchases, app downloads, or content engagement. Integrate with your CRM and marketing stack to attribute revenue to specific QR campaigns.</p>
|
||||
|
||||
<h2>Advanced Campaign Tracking Strategies</h2>
|
||||
<h3>UTM Tracking Integration</h3>
|
||||
<p>Append UTM parameters to your dynamic QR URLs for granular campaign attribution. Use consistent naming conventions across campaigns to compare performance in Google Analytics. UTM tracking bridges offline and online marketing, providing a unified view of customer journeys.</p>
|
||||
|
||||
<h3>Multi-Channel Attribution</h3>
|
||||
<p>Deploy branded QR codes across print ads, packaging, event tickets, business cards, and signage. Use unique QR codes for each channel to measure which touchpoints drive the highest ROI. Multi-channel attribution reveals the true value of integrated marketing campaigns.</p>
|
||||
|
||||
<h3>A/B Testing QR Designs</h3>
|
||||
<p>Test different branded QR styles—color schemes, logo placements, and call-to-action text—to optimize scan rates. Our analytics dashboard makes it easy to compare performance and roll out winning variations at scale.</p>
|
||||
|
||||
<h3>Retargeting and Remarketing</h3>
|
||||
<p>Leverage scan analytics to build retargeting audiences. Users who scan but don't convert can be re-engaged with display ads, email campaigns, and social media retargeting, boosting overall campaign ROI.</p>
|
||||
|
||||
<h2>Security and Compliance in QR Analytics</h2>
|
||||
<p>All QR Master scan analytics are GDPR-compliant, ensuring user data is collected, stored, and processed securely. We employ enterprise-grade security protocols to protect sensitive campaign data, making our platform ideal for bulk QR generation workflows in regulated industries.</p>
|
||||
<p>Secure QR codes prevent unauthorized access and malicious redirects. Our platform includes link validation, SSL encryption, and fraud detection to maintain trust and protect your brand reputation.</p>
|
||||
|
||||
<h2>Use Cases for QR Code Analytics</h2>
|
||||
<h3>Event Tracking</h3>
|
||||
<p>Deploy QR codes on event tickets, badges, and signage to track attendee engagement. Scan analytics reveal which sessions attract the most interest, optimize check-in flows, and measure event ROI.</p>
|
||||
|
||||
<h3>Print Marketing Campaigns</h3>
|
||||
<p>Use QR codes in magazine ads, direct mail, and packaging to bridge offline and online channels. Campaign tracking quantifies print campaign performance and justifies marketing spend.</p>
|
||||
|
||||
<h3>Business Card Analytics</h3>
|
||||
<p>Add dynamic QR codes to business cards to track networking effectiveness. Scan analytics show how many contacts engage, when they scan, and which follow-up actions they take.</p>
|
||||
|
||||
<h3>Bulk QR Generation for Retail</h3>
|
||||
<p>Generate thousands of product QR codes with our bulk QR tool. Track scan analytics at the SKU level to understand customer interest, optimize inventory, and personalize marketing.</p>
|
||||
|
||||
<h3>API-Driven Automation</h3>
|
||||
<p>Integrate QR code generation and analytics into your marketing automation platform via our API. Automate bulk QR creation, dynamic URL updates, and reporting workflows for enterprise-scale campaigns.</p>
|
||||
|
||||
<h2>Maximizing ROI with Scan Analytics</h2>
|
||||
<p>To maximize QR code ROI, continuously monitor scan analytics and iterate on campaign strategies. Test different branded QR designs, optimize UTM parameters, and leverage multi-channel attribution to understand the full customer journey.</p>
|
||||
<p>Combine scan analytics with customer data platforms (CDPs) and CRMs to personalize follow-up communications. Segment audiences based on scan behavior and deliver targeted offers that drive conversions.</p>
|
||||
<p>For bulk QR campaigns, use our analytics dashboard to identify trends across thousands of codes. Aggregate data reveals macro patterns while code-level metrics enable micro-optimizations.</p>
|
||||
|
||||
<h2>Conclusion</h2>
|
||||
<p>QR code analytics transforms QR codes from simple links into powerful marketing instruments. By tracking scan rates, user behavior, and campaign performance through advanced dashboards, marketers gain the insights needed to optimize dynamic QR campaigns, enhance branded experiences, and achieve measurable ROI.</p>
|
||||
<p>Whether you're deploying QR codes for event tracking, print marketing, bulk generation, or API-driven automation, scan analytics provides the data foundation for smarter, more effective campaigns. Start leveraging QR analytics today to unlock the full potential of your QR marketing strategy.</p>
|
||||
</div>`,
|
||||
},
|
||||
};
|
||||
|
||||
export default function BlogPostPage() {
|
||||
const params = useParams();
|
||||
const slug = params?.slug as string;
|
||||
const post = blogContent[slug as keyof typeof blogContent];
|
||||
function truncateAtWord(text: string, maxLength: number): string {
|
||||
if (text.length <= maxLength) return text;
|
||||
const truncated = text.slice(0, maxLength);
|
||||
const lastSpace = truncated.lastIndexOf(' ');
|
||||
return lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated;
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: { params: { slug: string } }): Promise<Metadata> {
|
||||
const post = blogPosts[params.slug];
|
||||
|
||||
if (!post) {
|
||||
return (
|
||||
<div className="py-20">
|
||||
<div className="container mx-auto px-4 text-center">
|
||||
<h1 className="text-4xl font-bold text-gray-900 mb-4">Post not found</h1>
|
||||
<p className="text-xl text-gray-600 mb-8">The blog post you're looking for doesn't exist.</p>
|
||||
<Link href="/blog">
|
||||
<Button>Back to Blog</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return {
|
||||
title: 'Post Not Found',
|
||||
};
|
||||
}
|
||||
|
||||
const title = truncateAtWord(`${post.title} - QR Analytics Tips`, 60);
|
||||
const description = truncateAtWord(post.excerpt, 160);
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
alternates: {
|
||||
canonical: `https://www.qrmaster.com/blog/${params.slug}`,
|
||||
languages: {
|
||||
'x-default': `https://www.qrmaster.com/blog/${params.slug}`,
|
||||
en: `https://www.qrmaster.com/blog/${params.slug}`,
|
||||
},
|
||||
},
|
||||
openGraph: {
|
||||
title,
|
||||
description,
|
||||
url: `https://www.qrmaster.com/blog/${params.slug}`,
|
||||
type: 'article',
|
||||
publishedTime: post.datePublished,
|
||||
modifiedTime: post.dateModified,
|
||||
authors: [post.author],
|
||||
images: [
|
||||
{
|
||||
url: post.image,
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: post.imageAlt,
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
title,
|
||||
description,
|
||||
card: 'summary_large_image',
|
||||
images: [post.image],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default function BlogPostPage({ params }: { params: { slug: string } }) {
|
||||
const post = blogPosts[params.slug];
|
||||
|
||||
if (!post) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
const breadcrumbItems: BreadcrumbItem[] = [
|
||||
{ name: 'Home', url: '/' },
|
||||
{ name: 'Blog', url: '/blog' },
|
||||
{ name: post.title, url: `/blog/${post.slug}` },
|
||||
];
|
||||
|
||||
const schemas = [
|
||||
blogPostingSchema({
|
||||
title: post.title,
|
||||
description: post.excerpt,
|
||||
slug: post.slug,
|
||||
author: post.author,
|
||||
authorUrl: post.authorUrl,
|
||||
datePublished: post.datePublished,
|
||||
dateModified: post.dateModified,
|
||||
image: post.image,
|
||||
}),
|
||||
breadcrumbSchema(breadcrumbItems),
|
||||
];
|
||||
|
||||
if (post.howTo) {
|
||||
schemas.push(howToSchema(post.howTo));
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="py-20">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<Link href="/blog" className="inline-flex items-center text-primary-600 hover:text-primary-700 mb-8">
|
||||
<svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
|
||||
</svg>
|
||||
Back to Blog
|
||||
</Link>
|
||||
<>
|
||||
<SeoJsonLd data={schemas} />
|
||||
<div className="py-20 bg-gradient-to-b from-gray-50 to-white">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<Breadcrumbs items={breadcrumbItems} />
|
||||
|
||||
<article>
|
||||
<header className="mb-8">
|
||||
<div className="flex items-center space-x-4 mb-4">
|
||||
<Badge variant="info">{post.category}</Badge>
|
||||
<span className="text-gray-500">{post.readTime}</span>
|
||||
<span className="text-gray-500">{post.date}</span>
|
||||
<article className="bg-white rounded-2xl shadow-sm p-8 md:p-12">
|
||||
<header className="mb-10">
|
||||
<div className="flex items-center flex-wrap gap-3 mb-6">
|
||||
<Badge variant="info">{post.category}</Badge>
|
||||
<span className="text-gray-500 flex items-center">
|
||||
<svg className="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
{post.readTime} read
|
||||
</span>
|
||||
<span className="text-gray-500">By {post.author}</span>
|
||||
<span className="text-gray-500">{post.date}</span>
|
||||
</div>
|
||||
|
||||
<h1 className="text-4xl lg:text-5xl font-bold text-gray-900 mb-6">
|
||||
{post.title}
|
||||
</h1>
|
||||
|
||||
{post.answer && (
|
||||
<div className="bg-blue-50 border-l-4 border-blue-500 p-6 mb-8 rounded-r-lg">
|
||||
<h2 className="text-xl font-semibold mb-2 text-gray-900">Quick Answer</h2>
|
||||
<p className="text-lg text-gray-800 leading-relaxed">{post.answer}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="relative w-full h-96 rounded-2xl overflow-hidden shadow-lg mb-8">
|
||||
<Image
|
||||
src={post.image}
|
||||
alt={post.imageAlt}
|
||||
fill
|
||||
className="object-cover"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div
|
||||
className="prose prose-lg max-w-none
|
||||
prose-headings:font-bold prose-headings:text-gray-900
|
||||
prose-h2:text-3xl prose-h2:mt-12 prose-h2:mb-6
|
||||
prose-h3:text-2xl prose-h3:mt-8 prose-h3:mb-4
|
||||
prose-p:text-gray-700 prose-p:leading-relaxed prose-p:mb-6 prose-p:text-lg
|
||||
prose-ul:my-6 prose-ul:space-y-2
|
||||
prose-li:text-gray-700 prose-li:leading-relaxed
|
||||
prose-strong:text-gray-900 prose-strong:font-semibold"
|
||||
dangerouslySetInnerHTML={{ __html: post.content }}
|
||||
/>
|
||||
|
||||
{post.howTo && (
|
||||
<div className="mt-12 bg-gradient-to-br from-blue-50 to-indigo-50 p-8 rounded-2xl border border-blue-200">
|
||||
<h2 className="text-3xl font-bold text-gray-900 mb-6">{post.howTo.name}</h2>
|
||||
<p className="text-lg text-gray-700 mb-6 leading-relaxed">{post.howTo.description}</p>
|
||||
<ol className="space-y-6">
|
||||
{post.howTo.steps.map((step: any, index: number) => (
|
||||
<li key={index} className="flex items-start">
|
||||
<span className="flex-shrink-0 w-10 h-10 bg-blue-600 text-white rounded-full flex items-center justify-center font-bold text-lg mr-4">
|
||||
{index + 1}
|
||||
</span>
|
||||
<div className="flex-1">
|
||||
<h3 className="font-semibold text-xl mb-2 text-gray-900">{step.name}</h3>
|
||||
<p className="text-gray-700 leading-relaxed">{step.text}</p>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mt-16 p-10 bg-gradient-to-br from-primary-50 to-primary-100 rounded-2xl text-center border border-primary-200">
|
||||
<h2 className="text-3xl font-bold text-gray-900 mb-4">
|
||||
Ready to Track Your QR Campaigns?
|
||||
</h2>
|
||||
<p className="text-lg text-gray-700 mb-8 max-w-2xl mx-auto leading-relaxed">
|
||||
Start creating professional dynamic QR codes with advanced scan analytics, campaign tracking, and real-time insights.
|
||||
</p>
|
||||
<Link href="/create">
|
||||
<Button size="lg">Create QR Code Free</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<h1 className="text-4xl lg:text-5xl font-bold text-gray-900 mb-4">
|
||||
{post.title}
|
||||
</h1>
|
||||
</header>
|
||||
|
||||
<div
|
||||
className="prose prose-lg max-w-none"
|
||||
dangerouslySetInnerHTML={{ __html: post.content }}
|
||||
/>
|
||||
|
||||
<div className="mt-12 p-8 bg-primary-50 rounded-xl text-center">
|
||||
<h2 className="text-2xl font-bold text-gray-900 mb-4">
|
||||
Ready to create your QR codes?
|
||||
</h2>
|
||||
<p className="text-gray-600 mb-6">
|
||||
Start creating professional QR codes with advanced tracking and analytics.
|
||||
</p>
|
||||
<Link href="/dashboard">
|
||||
<Button size="lg">Get Started Free</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</article>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,76 +1,128 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import type { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import SeoJsonLd from '@/components/SeoJsonLd';
|
||||
import { websiteSchema } from '@/lib/schema';
|
||||
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/Card';
|
||||
import { Badge } from '@/components/ui/Badge';
|
||||
|
||||
function truncateAtWord(text: string, maxLength: number): string {
|
||||
if (text.length <= maxLength) return text;
|
||||
const truncated = text.slice(0, maxLength);
|
||||
const lastSpace = truncated.lastIndexOf(' ');
|
||||
return lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated;
|
||||
}
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
const title = truncateAtWord('QR Insights: Latest QR Strategies', 60);
|
||||
const description = truncateAtWord(
|
||||
'Expert guides on QR analytics, dynamic codes & smart marketing uses.',
|
||||
160
|
||||
);
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
alternates: {
|
||||
canonical: 'https://www.qrmaster.com/blog',
|
||||
languages: {
|
||||
'x-default': 'https://www.qrmaster.com/blog',
|
||||
en: 'https://www.qrmaster.com/blog',
|
||||
},
|
||||
},
|
||||
openGraph: {
|
||||
title,
|
||||
description,
|
||||
url: 'https://www.qrmaster.com/blog',
|
||||
type: 'website',
|
||||
},
|
||||
twitter: {
|
||||
title,
|
||||
description,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const blogPosts = [
|
||||
{
|
||||
slug: 'qr-code-analytics',
|
||||
title: 'QR Code Analytics: Track, Measure & Optimize Campaigns',
|
||||
excerpt: 'Learn how to leverage scan analytics, campaign tracking, and dashboard insights to maximize QR code ROI.',
|
||||
date: 'October 16, 2025',
|
||||
readTime: '8 Min',
|
||||
category: 'Analytics',
|
||||
image: 'https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=800&q=80',
|
||||
},
|
||||
{
|
||||
slug: 'qr-codes-im-restaurant',
|
||||
title: 'QR-Codes im Restaurant: Die digitale Revolution der Speisekarte',
|
||||
excerpt: 'Erfahren Sie, wie QR-Codes die Gastronomie revolutionieren und welche Vorteile sie für Restaurants und Gäste bieten.',
|
||||
date: '2024-01-15',
|
||||
title: 'QR Codes in Restaurants: The Digital Menu Revolution',
|
||||
excerpt: 'Discover how QR codes are revolutionizing the restaurant industry and what benefits they offer for restaurants and guests.',
|
||||
date: 'January 15, 2024',
|
||||
readTime: '5 Min',
|
||||
category: 'Gastronomie',
|
||||
image: '🍽️',
|
||||
category: 'Restaurant',
|
||||
image: 'https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?w=800&q=80',
|
||||
},
|
||||
{
|
||||
slug: 'dynamische-vs-statische-qr-codes',
|
||||
title: 'Dynamische vs. Statische QR-Codes: Was ist der Unterschied?',
|
||||
excerpt: 'Ein umfassender Vergleich zwischen dynamischen und statischen QR-Codes und wann Sie welchen Typ verwenden sollten.',
|
||||
date: '2024-01-10',
|
||||
title: 'Dynamic vs Static QR Codes: What\'s the Difference?',
|
||||
excerpt: 'A comprehensive comparison between dynamic and static QR codes and when you should use each type.',
|
||||
date: 'January 10, 2024',
|
||||
readTime: '3 Min',
|
||||
category: 'Grundlagen',
|
||||
image: '📊',
|
||||
},
|
||||
{
|
||||
slug: 'qr-code-marketing-strategien',
|
||||
title: 'QR-Code Marketing-Strategien für 2024',
|
||||
excerpt: 'Die besten Marketing-Strategien mit QR-Codes für Ihr Unternehmen im Jahr 2024.',
|
||||
date: '2024-01-05',
|
||||
readTime: '7 Min',
|
||||
category: 'Marketing',
|
||||
image: '📈',
|
||||
category: 'Basics',
|
||||
image: 'https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=800&q=80',
|
||||
},
|
||||
];
|
||||
|
||||
export default function BlogPage() {
|
||||
return (
|
||||
<div className="py-20">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="text-center mb-12">
|
||||
<h1 className="text-4xl lg:text-5xl font-bold text-gray-900 mb-4">
|
||||
Blog & Resources
|
||||
</h1>
|
||||
<p className="text-xl text-gray-600">
|
||||
Learn about QR codes, best practices, and industry insights
|
||||
</p>
|
||||
</div>
|
||||
<>
|
||||
<SeoJsonLd data={websiteSchema()} />
|
||||
<div className="py-20 bg-gradient-to-b from-gray-50 to-white">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="text-center mb-16">
|
||||
<h1 className="text-4xl lg:text-5xl font-bold text-gray-900 mb-6">
|
||||
QR Code Insights
|
||||
</h1>
|
||||
<p className="text-xl text-gray-600 max-w-2xl mx-auto">
|
||||
Expert guides on dynamic QR codes, campaign tracking, UTM analytics, and smart marketing use cases.
|
||||
Discover how-to tutorials and best practices for QR code analytics.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8 max-w-6xl mx-auto">
|
||||
{blogPosts.map((post) => (
|
||||
<Link key={post.slug} href={`/blog/${post.slug}`}>
|
||||
<Card hover className="h-full">
|
||||
<CardHeader>
|
||||
<div className="text-4xl mb-4 text-center bg-gray-100 rounded-lg py-8">
|
||||
{post.image}
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8 max-w-6xl mx-auto">
|
||||
{blogPosts.map((post) => (
|
||||
<Link key={post.slug} href={`/blog/${post.slug}`}>
|
||||
<Card hover className="h-full overflow-hidden shadow-md hover:shadow-xl transition-all duration-300">
|
||||
<div className="relative h-56 overflow-hidden">
|
||||
<Image
|
||||
src={post.image}
|
||||
alt={`${post.title} - QR code guide showing ${post.category.toLowerCase()} strategies`}
|
||||
width={800}
|
||||
height={600}
|
||||
className="w-full h-full object-cover transition-transform duration-500 hover:scale-110"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<Badge variant="info">{post.category}</Badge>
|
||||
<span className="text-sm text-gray-500">{post.readTime}</span>
|
||||
</div>
|
||||
<CardTitle className="text-xl">{post.title}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="text-gray-600 mb-4">{post.excerpt}</p>
|
||||
<p className="text-sm text-gray-500">{post.date}</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Link>
|
||||
))}
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<Badge variant="info">{post.category}</Badge>
|
||||
<span className="text-sm text-gray-500 font-medium">{post.readTime} read</span>
|
||||
</div>
|
||||
<CardTitle className="text-xl leading-tight mb-3">{post.title}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0">
|
||||
<p className="text-gray-600 mb-4 leading-relaxed">{post.excerpt}</p>
|
||||
<div className="flex items-center justify-between pt-4 border-t border-gray-100">
|
||||
<p className="text-sm text-gray-500">{post.date}</p>
|
||||
<span className="text-primary-600 text-sm font-medium">Read more →</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,143 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { FAQ } from '@/components/marketing/FAQ';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import type { Metadata } from 'next';
|
||||
import SeoJsonLd from '@/components/SeoJsonLd';
|
||||
import { faqPageSchema } from '@/lib/schema';
|
||||
import { Card, CardContent } from '@/components/ui/Card';
|
||||
|
||||
function truncateAtWord(text: string, maxLength: number): string {
|
||||
if (text.length <= maxLength) return text;
|
||||
const truncated = text.slice(0, maxLength);
|
||||
const lastSpace = truncated.lastIndexOf(' ');
|
||||
return lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated;
|
||||
}
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
const title = truncateAtWord('QR Master FAQ: Dynamic & Bulk QR', 60);
|
||||
const description = truncateAtWord(
|
||||
'All answers: dynamic QR, security, analytics, bulk, events & print.',
|
||||
160
|
||||
);
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
alternates: {
|
||||
canonical: 'https://www.qrmaster.com/faq',
|
||||
languages: {
|
||||
'x-default': 'https://www.qrmaster.com/faq',
|
||||
en: 'https://www.qrmaster.com/faq',
|
||||
},
|
||||
},
|
||||
openGraph: {
|
||||
title,
|
||||
description,
|
||||
url: 'https://www.qrmaster.com/faq',
|
||||
type: 'website',
|
||||
},
|
||||
twitter: {
|
||||
title,
|
||||
description,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const faqs = [
|
||||
{
|
||||
question: 'What is a dynamic QR code?',
|
||||
answer: 'A dynamic QR code allows you to change the destination URL after the code has been created and printed. Unlike static QR codes, dynamic codes redirect through a short URL that you control, enabling real-time updates, scan analytics, and campaign tracking without reprinting the code.',
|
||||
},
|
||||
{
|
||||
question: 'How do I track QR scans?',
|
||||
answer: 'QR Master provides a comprehensive analytics dashboard that tracks every scan in real-time. You can monitor scan rates, geographic locations, device types, timestamps, and user behavior. Enable UTM parameters to integrate with Google Analytics for advanced campaign tracking and conversion attribution.',
|
||||
},
|
||||
{
|
||||
question: 'What security features does QR Master offer?',
|
||||
answer: 'QR Master employs enterprise-grade security including SSL encryption, link validation to prevent malicious redirects, fraud detection, and GDPR-compliant data handling. All scan analytics are stored securely and access is protected with multi-factor authentication for business accounts.',
|
||||
},
|
||||
{
|
||||
question: 'Can I generate bulk QR codes for print?',
|
||||
answer: 'Yes. Our bulk QR generation tool allows you to create thousands of QR codes at once by uploading a CSV file. Each code can be customized with unique URLs, UTM parameters, and branding. Download print-ready files in SVG, PNG, or PDF formats optimized for high-resolution printing.',
|
||||
},
|
||||
{
|
||||
question: 'How do I brand my QR codes?',
|
||||
answer: 'QR Master offers full customization options including custom colors, logo embedding, rounded corners, and pattern styles. Branded QR codes maintain scannability while matching your brand identity. Upload your logo, choose your color palette, and preview designs before downloading.',
|
||||
},
|
||||
{
|
||||
question: 'Is scan analytics GDPR compliant?',
|
||||
answer: 'Yes. All QR Master analytics are fully GDPR compliant. We collect only necessary data, provide transparent privacy policies, allow users to opt out, and store data securely in EU-compliant data centers. You maintain full control over data retention and deletion.',
|
||||
},
|
||||
{
|
||||
question: 'Can QR Master track campaigns with UTM?',
|
||||
answer: 'Absolutely. QR Master supports UTM parameter integration for all dynamic QR codes. Automatically append source, medium, campaign, term, and content parameters to track QR performance in Google Analytics, Adobe Analytics, and other marketing platforms. UTM tracking enables multi-channel attribution and ROI measurement.',
|
||||
},
|
||||
{
|
||||
question: 'Difference between static and dynamic QR codes?',
|
||||
answer: 'Static QR codes encode the destination URL directly in the code pattern and cannot be changed after creation. Dynamic QR codes use a short redirect URL, allowing you to update destinations, track scans, enable/disable codes, and gather analytics—all without reprinting. Dynamic codes are essential for professional marketing campaigns.',
|
||||
},
|
||||
{
|
||||
question: 'How are QR codes used for events?',
|
||||
answer: 'QR codes streamline event check-ins, ticket validation, attendee tracking, and engagement measurement. Generate unique codes for each ticket, track scan times and locations, enable contactless entry, and analyze attendee behavior. Event organizers use QR analytics to measure session popularity and optimize future events.',
|
||||
},
|
||||
{
|
||||
question: 'Can I make QR codes for business cards?',
|
||||
answer: 'Yes. QR codes on business cards provide instant contact sharing via vCard format, link to your portfolio or LinkedIn profile, and track networking effectiveness. Use branded QR codes that match your card design, and leverage scan analytics to see how many contacts engage and when they follow up.',
|
||||
},
|
||||
{
|
||||
question: 'How do I use QR codes for bulk marketing?',
|
||||
answer: 'Bulk QR codes enable scalable campaigns across print ads, packaging, direct mail, and retail displays. Generate thousands of codes with unique tracking URLs, distribute them across channels, and use analytics to measure which placements drive the highest engagement. Bulk generation supports CSV upload, API integration, and automated workflows.',
|
||||
},
|
||||
{
|
||||
question: 'Is API access available for bulk QR generation?',
|
||||
answer: 'Yes. QR Master offers a developer-friendly REST API for programmatic QR code generation, URL management, and analytics retrieval. Integrate QR creation into your CRM, marketing automation platform, or e-commerce system. API access is included in Business plans and supports bulk operations, webhooks, and real-time updates.',
|
||||
},
|
||||
];
|
||||
|
||||
export default function FAQPage() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="py-20">
|
||||
<FAQ t={t} />
|
||||
</div>
|
||||
<>
|
||||
<SeoJsonLd data={faqPageSchema(faqs)} />
|
||||
<div className="py-20 bg-gradient-to-b from-gray-50 to-white">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<div className="text-center mb-16">
|
||||
<h1 className="text-4xl lg:text-5xl font-bold text-gray-900 mb-6">
|
||||
Frequently Asked Questions
|
||||
</h1>
|
||||
<p className="text-xl text-gray-600">
|
||||
Everything you need to know about dynamic QR codes, security, analytics, bulk generation, events, and print quality.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-6">
|
||||
{faqs.map((faq, index) => (
|
||||
<Card key={index} className="border-l-4 border-blue-500">
|
||||
<CardContent className="p-8">
|
||||
<h2 className="text-2xl font-semibold mb-4 text-gray-900">
|
||||
{faq.question}
|
||||
</h2>
|
||||
<p className="text-lg text-gray-700 leading-relaxed">
|
||||
{faq.answer}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-16 bg-blue-50 border-l-4 border-blue-500 p-8 rounded-r-lg">
|
||||
<h2 className="text-2xl font-bold mb-4 text-gray-900">
|
||||
Still have questions?
|
||||
</h2>
|
||||
<p className="text-lg text-gray-700 mb-6 leading-relaxed">
|
||||
Our support team is here to help. Contact us at{' '}
|
||||
<a href="mailto:support@qrmaster.com" className="text-blue-600 hover:text-blue-700 font-semibold">
|
||||
support@qrmaster.com
|
||||
</a>{' '}
|
||||
or reach out through our live chat.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import React, { useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import en from '@/i18n/en.json';
|
||||
|
||||
export default function MarketingLayout({
|
||||
children,
|
||||
@@ -12,14 +12,16 @@ export default function MarketingLayout({
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const pathname = usePathname();
|
||||
const { t, locale, setLocale } = useTranslation();
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
|
||||
// Always use English for marketing pages
|
||||
const t = en;
|
||||
|
||||
const navigation = [
|
||||
{ name: t('nav.features'), href: '/#features' },
|
||||
{ name: t('nav.pricing'), href: '/pricing' },
|
||||
{ name: t('nav.faq'), href: '/faq' },
|
||||
{ name: t('nav.blog'), href: '/blog' },
|
||||
{ name: t.nav.features, href: '/#features' },
|
||||
{ name: t.nav.pricing, href: '/#pricing' },
|
||||
{ name: t.nav.faq, href: '/#faq' },
|
||||
{ name: t.nav.blog, href: '/blog' },
|
||||
];
|
||||
|
||||
return (
|
||||
@@ -49,16 +51,8 @@ export default function MarketingLayout({
|
||||
|
||||
{/* Right Actions */}
|
||||
<div className="hidden md:flex items-center space-x-4">
|
||||
{/* Language Switcher */}
|
||||
<button
|
||||
onClick={() => setLocale(locale === 'en' ? 'de' : 'en')}
|
||||
className="text-gray-600 hover:text-gray-900 font-medium"
|
||||
>
|
||||
{locale === 'en' ? '🇩🇪 DE' : '🇬🇧 EN'}
|
||||
</button>
|
||||
|
||||
<Link href="/login">
|
||||
<Button variant="outline">{t('nav.login')}</Button>
|
||||
<Button variant="outline">{t.nav.login}</Button>
|
||||
</Link>
|
||||
|
||||
<Link href="/signup">
|
||||
@@ -96,7 +90,7 @@ export default function MarketingLayout({
|
||||
</Link>
|
||||
))}
|
||||
<Link href="/login" onClick={() => setMobileMenuOpen(false)}>
|
||||
<Button variant="outline" className="w-full">{t('nav.login')}</Button>
|
||||
<Button variant="outline" className="w-full">{t.nav.login}</Button>
|
||||
</Link>
|
||||
<Link href="/signup" onClick={() => setMobileMenuOpen(false)}>
|
||||
<Button className="w-full">Get Started Free</Button>
|
||||
@@ -128,8 +122,8 @@ export default function MarketingLayout({
|
||||
<h3 className="font-semibold mb-4">Product</h3>
|
||||
<ul className="space-y-2 text-gray-400">
|
||||
<li><Link href="/#features" className="hover:text-white">Features</Link></li>
|
||||
<li><Link href="/pricing" className="hover:text-white">Pricing</Link></li>
|
||||
<li><Link href="/faq" className="hover:text-white">FAQ</Link></li>
|
||||
<li><Link href="/#pricing" className="hover:text-white">Pricing</Link></li>
|
||||
<li><Link href="/#faq" className="hover:text-white">FAQ</Link></li>
|
||||
<li><Link href="/blog" className="hover:text-white">Blog</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -1,77 +1,51 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { Hero } from '@/components/marketing/Hero';
|
||||
import { StatsStrip } from '@/components/marketing/StatsStrip';
|
||||
import { TemplateCards } from '@/components/marketing/TemplateCards';
|
||||
import { InstantGenerator } from '@/components/marketing/InstantGenerator';
|
||||
import { StaticVsDynamic } from '@/components/marketing/StaticVsDynamic';
|
||||
import { Features } from '@/components/marketing/Features';
|
||||
import { Pricing } from '@/components/marketing/Pricing';
|
||||
import { FAQ } from '@/components/marketing/FAQ';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import type { Metadata } from 'next';
|
||||
import SeoJsonLd from '@/components/SeoJsonLd';
|
||||
import { organizationSchema, websiteSchema } from '@/lib/schema';
|
||||
import HomePageClient from '@/components/marketing/HomePageClient';
|
||||
|
||||
function truncateAtWord(text: string, maxLength: number): string {
|
||||
if (text.length <= maxLength) return text;
|
||||
const truncated = text.slice(0, maxLength);
|
||||
const lastSpace = truncated.lastIndexOf(' ');
|
||||
return lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated;
|
||||
}
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
const title = truncateAtWord('QR Master: Dynamic QR Generator', 60);
|
||||
const description = truncateAtWord(
|
||||
'Dynamic QR, branding, bulk generation & analytics for all campaigns.',
|
||||
160
|
||||
);
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
alternates: {
|
||||
canonical: 'https://www.qrmaster.com/',
|
||||
languages: {
|
||||
'x-default': 'https://www.qrmaster.com/',
|
||||
en: 'https://www.qrmaster.com/',
|
||||
},
|
||||
},
|
||||
openGraph: {
|
||||
title,
|
||||
description,
|
||||
url: 'https://www.qrmaster.com/',
|
||||
type: 'website',
|
||||
},
|
||||
twitter: {
|
||||
title,
|
||||
description,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default function HomePage() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const industries = [
|
||||
'Restaurant Chain',
|
||||
'Tech Startup',
|
||||
'Real Estate',
|
||||
'Event Agency',
|
||||
'Retail Store',
|
||||
'Healthcare',
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<Hero t={t} />
|
||||
<StatsStrip t={t} />
|
||||
|
||||
{/* Industry Buttons */}
|
||||
<section className="py-8">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="flex flex-wrap justify-center gap-3">
|
||||
{industries.map((industry) => (
|
||||
<Button key={industry} variant="outline" size="sm">
|
||||
{industry}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<TemplateCards t={t} />
|
||||
<InstantGenerator t={t} />
|
||||
<StaticVsDynamic t={t} />
|
||||
<Features t={t} />
|
||||
|
||||
{/* Pricing Teaser */}
|
||||
<section className="py-16 bg-primary-50">
|
||||
<div className="container mx-auto px-4 text-center">
|
||||
<h2 className="text-3xl lg:text-4xl font-bold text-gray-900 mb-4">
|
||||
Ready to get started?
|
||||
</h2>
|
||||
<p className="text-xl text-gray-600 mb-8">
|
||||
Choose the perfect plan for your needs
|
||||
</p>
|
||||
<Button size="lg">View Pricing Plans</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ Teaser */}
|
||||
<section className="py-16">
|
||||
<div className="container mx-auto px-4 text-center">
|
||||
<h2 className="text-3xl lg:text-4xl font-bold text-gray-900 mb-4">
|
||||
Have questions?
|
||||
</h2>
|
||||
<p className="text-xl text-gray-600 mb-8">
|
||||
Check out our frequently asked questions
|
||||
</p>
|
||||
<Button variant="outline" size="lg">View FAQ</Button>
|
||||
</div>
|
||||
</section>
|
||||
<SeoJsonLd data={[organizationSchema(), websiteSchema()]} />
|
||||
<HomePageClient />
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
267
src/app/(marketing)/pricing/page.tsx
Normal file
267
src/app/(marketing)/pricing/page.tsx
Normal file
@@ -0,0 +1,267 @@
|
||||
import React from 'react';
|
||||
import type { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import SeoJsonLd from '@/components/SeoJsonLd';
|
||||
import { productSchema } from '@/lib/schema';
|
||||
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/Card';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { Badge } from '@/components/ui/Badge';
|
||||
|
||||
function truncateAtWord(text: string, maxLength: number): string {
|
||||
if (text.length <= maxLength) return text;
|
||||
const truncated = text.slice(0, maxLength);
|
||||
const lastSpace = truncated.lastIndexOf(' ');
|
||||
return lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated;
|
||||
}
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
const title = truncateAtWord('QR Master Pricing & Bulk Plans', 60);
|
||||
const description = truncateAtWord(
|
||||
'Choose flexible plans for bulk QR generation, analytics & branding.',
|
||||
160
|
||||
);
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
alternates: {
|
||||
canonical: 'https://www.qrmaster.com/pricing',
|
||||
languages: {
|
||||
'x-default': 'https://www.qrmaster.com/pricing',
|
||||
en: 'https://www.qrmaster.com/pricing',
|
||||
},
|
||||
},
|
||||
openGraph: {
|
||||
title,
|
||||
description,
|
||||
url: 'https://www.qrmaster.com/pricing',
|
||||
type: 'website',
|
||||
},
|
||||
twitter: {
|
||||
title,
|
||||
description,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default function PricingPage() {
|
||||
const productData = {
|
||||
name: 'QR Master Plans',
|
||||
description: 'Flexible pricing for dynamic QR codes, bulk generation, branded designs, and analytics.',
|
||||
offers: [
|
||||
{
|
||||
name: 'Free Plan',
|
||||
price: '0',
|
||||
priceCurrency: 'USD',
|
||||
availability: 'https://schema.org/InStock',
|
||||
url: 'https://www.qrmaster.com/pricing',
|
||||
},
|
||||
{
|
||||
name: 'Pro Plan',
|
||||
price: '29',
|
||||
priceCurrency: 'USD',
|
||||
availability: 'https://schema.org/InStock',
|
||||
url: 'https://www.qrmaster.com/pricing',
|
||||
},
|
||||
{
|
||||
name: 'Business Plan',
|
||||
price: '99',
|
||||
priceCurrency: 'USD',
|
||||
availability: 'https://schema.org/InStock',
|
||||
url: 'https://www.qrmaster.com/pricing',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const plans = [
|
||||
{
|
||||
name: 'Free',
|
||||
price: '$0',
|
||||
interval: '/mo',
|
||||
description: 'Perfect for personal projects',
|
||||
features: [
|
||||
'10 Dynamic QR Codes',
|
||||
'Basic Scan Analytics',
|
||||
'Standard QR Design Templates',
|
||||
'Community Support',
|
||||
],
|
||||
cta: 'Get Started',
|
||||
ctaLink: '/signup',
|
||||
popular: false,
|
||||
},
|
||||
{
|
||||
name: 'Pro',
|
||||
price: '$29',
|
||||
interval: '/mo',
|
||||
description: 'For professionals and small teams',
|
||||
features: [
|
||||
'Unlimited Dynamic QR Codes',
|
||||
'Advanced Scan Analytics',
|
||||
'Branded QR Codes with Custom Colors & Logo',
|
||||
'Bulk QR Generation (up to 1,000)',
|
||||
'UTM Campaign Tracking',
|
||||
'Download as SVG/PNG/PDF',
|
||||
'Priority Support',
|
||||
],
|
||||
cta: 'Start Pro Trial',
|
||||
ctaLink: '/signup?plan=pro',
|
||||
popular: true,
|
||||
},
|
||||
{
|
||||
name: 'Business',
|
||||
price: '$99',
|
||||
interval: '/mo',
|
||||
description: 'For agencies and enterprises',
|
||||
features: [
|
||||
'Everything in Pro',
|
||||
'Unlimited Bulk QR Generation',
|
||||
'API Access for Automation',
|
||||
'White-Label Options',
|
||||
'Advanced Security Features',
|
||||
'Custom Integrations',
|
||||
'Dedicated Account Manager',
|
||||
'SLA Guarantee',
|
||||
],
|
||||
cta: 'Contact Sales',
|
||||
ctaLink: '/signup?plan=business',
|
||||
popular: false,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<SeoJsonLd data={productSchema(productData)} />
|
||||
<div className="py-20 bg-gradient-to-b from-gray-50 to-white">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="text-center mb-16">
|
||||
<h1 className="text-4xl lg:text-5xl font-bold text-gray-900 mb-6">
|
||||
Pricing Plans
|
||||
</h1>
|
||||
<p className="text-xl text-gray-600 max-w-2xl mx-auto">
|
||||
Choose flexible plans for bulk QR generation, analytics, and branded QR codes.
|
||||
Start free, upgrade anytime.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid md:grid-cols-3 gap-8 max-w-6xl mx-auto mb-20">
|
||||
{plans.map((plan, index) => (
|
||||
<Card
|
||||
key={index}
|
||||
className={`relative ${
|
||||
plan.popular
|
||||
? 'border-2 border-blue-600 shadow-xl transform scale-105'
|
||||
: 'border-gray-200'
|
||||
}`}
|
||||
>
|
||||
{plan.popular && (
|
||||
<div className="absolute -top-4 left-1/2 transform -translate-x-1/2">
|
||||
<Badge variant="info" className="px-4 py-1 text-sm font-semibold">
|
||||
Most Popular
|
||||
</Badge>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<CardHeader className="text-center pb-6">
|
||||
<CardTitle className="text-2xl mb-2">{plan.name}</CardTitle>
|
||||
<p className="text-sm text-gray-600 mb-6">{plan.description}</p>
|
||||
|
||||
<div className="flex items-baseline justify-center">
|
||||
<span className="text-5xl font-bold text-gray-900">{plan.price}</span>
|
||||
<span className="text-gray-600 ml-2 text-lg">{plan.interval}</span>
|
||||
</div>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent className="space-y-6">
|
||||
<ul className="space-y-3 mb-8">
|
||||
{plan.features.map((feature, fIndex) => (
|
||||
<li key={fIndex} className="flex items-start space-x-3">
|
||||
<svg
|
||||
className="w-5 h-5 text-green-500 flex-shrink-0 mt-0.5"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<span className="text-gray-700">{feature}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<Link href={plan.ctaLink}>
|
||||
<Button
|
||||
variant={plan.popular ? 'primary' : 'outline'}
|
||||
className="w-full"
|
||||
size="lg"
|
||||
>
|
||||
{plan.cta}
|
||||
</Button>
|
||||
</Link>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* FAQ Section */}
|
||||
<div className="mt-20 max-w-3xl mx-auto">
|
||||
<h2 className="text-3xl font-bold text-center mb-12 text-gray-900">
|
||||
Pricing FAQs
|
||||
</h2>
|
||||
<div className="space-y-6">
|
||||
<Card>
|
||||
<CardContent className="p-6">
|
||||
<h3 className="font-semibold text-lg mb-3 text-gray-900">
|
||||
Can I cancel my subscription anytime?
|
||||
</h3>
|
||||
<p className="text-gray-700 leading-relaxed">
|
||||
Yes, you can cancel your subscription at any time. Your account will remain active
|
||||
until the end of your current billing period. No refunds for partial months.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardContent className="p-6">
|
||||
<h3 className="font-semibold text-lg mb-3 text-gray-900">
|
||||
What happens to my QR codes if I downgrade?
|
||||
</h3>
|
||||
<p className="text-gray-700 leading-relaxed">
|
||||
All your existing QR codes remain active and functional. You won't be able to create
|
||||
new codes if you exceed your new plan's limit, but existing codes continue working.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardContent className="p-6">
|
||||
<h3 className="font-semibold text-lg mb-3 text-gray-900">
|
||||
Do you offer annual billing?
|
||||
</h3>
|
||||
<p className="text-gray-700 leading-relaxed">
|
||||
Yes! Annual billing saves you 17% compared to monthly billing. Contact sales for
|
||||
custom annual contracts with additional discounts for enterprise customers.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardContent className="p-6">
|
||||
<h3 className="font-semibold text-lg mb-3 text-gray-900">
|
||||
Is there a free trial for paid plans?
|
||||
</h3>
|
||||
<p className="text-gray-700 leading-relaxed">
|
||||
Yes, all paid plans include a 14-day free trial. No credit card required to start.
|
||||
Test all premium features before committing to a paid plan.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user