This commit is contained in:
Timo Knuth
2026-05-27 20:37:15 +02:00
parent 09f5859af2
commit a7cbbee084
15 changed files with 1181 additions and 48 deletions

View File

@@ -14,7 +14,7 @@ const competitor = competitors['bitly'];
export const metadata: Metadata = {
title: {
absolute: 'Bitly QR Code Alternative Purpose-Built for QR Campaigns | QR Master',
absolute: 'QR Master vs Bitly QR Codes | Bitly Alternative',
},
description:
'Looking for a Bitly alternative for QR codes? Bitly\'s Core plan costs $10/month but only allows 2 QR codes total. QR Master is purpose-built for QR code management — 50 codes at €9/month, bulk creation, GDPR analytics. From €0.',
@@ -24,7 +24,7 @@ export const metadata: Metadata = {
canonical: 'https://www.qrmaster.net/alternatives/bitly',
},
openGraph: {
title: 'Bitly QR Code Alternative Purpose-Built for QR Campaigns',
title: 'QR Master vs Bitly QR Codes | Bitly Alternative',
description:
'Bitly\'s Core plan costs $10/month but only gives you 2 QR codes. QR Master gives you 50 dynamic QR codes at €9/month — purpose-built for QR workflows, bulk creation, and GDPR analytics.',
url: 'https://www.qrmaster.net/alternatives/bitly',
@@ -32,7 +32,7 @@ export const metadata: Metadata = {
images: ['/og-image.png'],
},
twitter: {
title: 'Bitly QR Code Alternative Purpose-Built for QR Campaigns',
title: 'QR Master vs Bitly QR Codes | Bitly Alternative',
description:
'Bitly gives you 2 QR codes for $10/month. QR Master gives you 50 at €9/month — purpose-built for real QR campaigns, not link shortening with QR as an afterthought.',
},
@@ -40,6 +40,34 @@ export const metadata: Metadata = {
const comparisonRows = competitor.features;
const atAGlanceRows = [
{
useCase: 'A couple of QR codes',
bitly: 'Reasonable if you already pay for Bitly and only need 1-2 QR codes.',
qrMaster: 'Free plan includes 3 active dynamic QR codes plus unlimited static codes.',
},
{
useCase: 'Marketing campaign with many placements',
bitly: 'Entry plans hit QR count limits quickly.',
qrMaster: 'Pro includes 50 dynamic QR codes; Business includes 500.',
},
{
useCase: 'Bulk QR creation',
bitly: 'No dedicated bulk QR generator.',
qrMaster: 'CSV and Excel upload creates up to 1,000 unique QR codes per batch.',
},
{
useCase: 'QR campaign analytics',
bitly: 'Strong link analytics, but QR is a secondary workflow.',
qrMaster: 'QR-first scan analytics with device, country, time, and UTM context.',
},
{
useCase: 'Migration risk',
bitly: 'Printed codes depend on Bitly redirect infrastructure.',
qrMaster: 'Re-create destinations before canceling Bitly and replace codes on the next print cycle.',
},
];
const faqItems = [
{
question: 'How many QR codes does Bitly allow per plan?',
@@ -256,6 +284,41 @@ export default function BitlyAlternativePage() {
</div>
</section>
<section className="border-b bg-white py-20" style={{ borderColor: '#E4E0D9' }}>
<div className="container mx-auto max-w-5xl px-4 sm:px-6 lg:px-8">
<h2 className="mb-3 text-3xl font-bold tracking-tight sm:text-4xl" style={{ color: '#111110' }}>
QR Master vs Bitly at a glance
</h2>
<p className="mb-10 text-lg" style={{ color: '#71717A' }}>
Bitly is strongest as a link management platform. QR Master is stronger when QR codes are the main
campaign asset and you need predictable pricing, bulk creation, and QR-specific reporting.
</p>
<div className="overflow-hidden rounded-xl border" style={{ borderColor: '#E4E0D9' }}>
<div className="grid grid-cols-1 md:grid-cols-3" style={{ backgroundColor: '#F8F7F4' }}>
{['Use case', 'Bitly', 'QR Master'].map((heading) => (
<div key={heading} className="p-4 text-xs font-semibold uppercase tracking-wider" style={{ color: '#71717A' }}>
{heading}
</div>
))}
</div>
{atAGlanceRows.map((row, index) => (
<div
key={row.useCase}
className="grid grid-cols-1 md:grid-cols-3"
style={{
borderTop: '1px solid #E4E0D9',
backgroundColor: index % 2 === 0 ? '#FFFFFF' : '#FAFAF8',
}}
>
<div className="p-4 text-sm font-semibold" style={{ color: '#18181B' }}>{row.useCase}</div>
<div className="p-4 text-sm" style={{ color: '#52525B' }}>{row.bitly}</div>
<div className="p-4 text-sm font-medium" style={{ color: '#166534' }}>{row.qrMaster}</div>
</div>
))}
</div>
</div>
</section>
{/* Why Bitly is the Wrong Tool */}
<section className="py-24" style={{ backgroundColor: '#F8F7F4' }}>
<div className="container mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">

View File

@@ -14,7 +14,7 @@ const competitor = competitors['flowcode'];
export const metadata: Metadata = {
title: {
absolute: 'Flowcode Alternative No Forced Branding or Scan Interstitials | QR Master',
absolute: 'QR Master vs Flowcode | Flowcode Alternative Without Forced Branding',
},
description:
'Looking for a Flowcode alternative? QR Master gives you clean, customizable QR codes without Flowcode\'s logo or scan-hijacking interstitial pages — from €0 free, Pro at €9/month.',
@@ -24,7 +24,7 @@ export const metadata: Metadata = {
canonical: 'https://www.qrmaster.net/alternatives/flowcode',
},
openGraph: {
title: 'Flowcode Alternative No Forced Branding or Scan Interstitials',
title: 'QR Master vs Flowcode | Flowcode Alternative Without Forced Branding',
description:
'Flowcode puts its logo on your QR codes and routes scans through its own branded page. QR Master gives you full branding control from the start.',
url: 'https://www.qrmaster.net/alternatives/flowcode',
@@ -32,7 +32,7 @@ export const metadata: Metadata = {
images: ['/og-image.png'],
},
twitter: {
title: 'Flowcode Alternative No Forced Branding or Scan Interstitials',
title: 'QR Master vs Flowcode | Flowcode Alternative Without Forced Branding',
description:
'Flowcode puts its logo on your QR codes and routes scans through its own branded page. QR Master gives you full branding control from the start.',
},
@@ -40,6 +40,34 @@ export const metadata: Metadata = {
const comparisonRows = competitor.features;
const atAGlanceRows = [
{
useCase: 'Free branded QR codes',
flowcode: 'Flowcode branding can appear in the code style and scan path on lower tiers.',
qrMaster: 'No forced QR Master logo or branded interstitial page.',
},
{
useCase: 'White-label brand control',
flowcode: 'Meaningful white-label control is typically tied to higher paid tiers.',
qrMaster: 'Custom colors and logo support start on Pro at EUR 9/month.',
},
{
useCase: 'Direct scan experience',
flowcode: 'Lower-tier scans may pass through a Flowcode-branded interstitial.',
qrMaster: 'Dynamic codes redirect directly to the destination after scan logging.',
},
{
useCase: 'Bulk QR creation',
flowcode: 'No built-in CSV or Excel bulk QR generator.',
qrMaster: 'Business supports up to 1,000 unique QR codes per bulk upload.',
},
{
useCase: 'EU privacy posture',
flowcode: 'US platform; EU teams should review data processing terms.',
qrMaster: 'Scan analytics hash IPs server-side before storage.',
},
];
const faqItems = [
{
question: 'What is the Flowcode interstitial page and why does it matter?',
@@ -238,6 +266,41 @@ export default function FlowcodeAlternativePage() {
</div>
</section>
<section className="border-b bg-white py-20" style={{ borderColor: '#E4E0D9' }}>
<div className="container mx-auto max-w-5xl px-4 sm:px-6 lg:px-8">
<h2 className="mb-3 text-3xl font-bold tracking-tight sm:text-4xl" style={{ color: '#111110' }}>
QR Master vs Flowcode at a glance
</h2>
<p className="mb-10 text-lg" style={{ color: '#71717A' }}>
Flowcode is design-forward. QR Master is the cleaner fit when you need a neutral QR code, direct scan
experience, bulk creation, and predictable pricing.
</p>
<div className="overflow-hidden rounded-xl border" style={{ borderColor: '#E4E0D9' }}>
<div className="grid grid-cols-1 md:grid-cols-3" style={{ backgroundColor: '#F8F7F4' }}>
{['Use case', 'Flowcode', 'QR Master'].map((heading) => (
<div key={heading} className="p-4 text-xs font-semibold uppercase tracking-wider" style={{ color: '#71717A' }}>
{heading}
</div>
))}
</div>
{atAGlanceRows.map((row, index) => (
<div
key={row.useCase}
className="grid grid-cols-1 md:grid-cols-3"
style={{
borderTop: '1px solid #E4E0D9',
backgroundColor: index % 2 === 0 ? '#FFFFFF' : '#FAFAF8',
}}
>
<div className="p-4 text-sm font-semibold" style={{ color: '#18181B' }}>{row.useCase}</div>
<div className="p-4 text-sm" style={{ color: '#52525B' }}>{row.flowcode}</div>
<div className="p-4 text-sm font-medium" style={{ color: '#166534' }}>{row.qrMaster}</div>
</div>
))}
</div>
</div>
</section>
{/* The Real Problem with Flowcode */}
<section className="py-24" style={{ backgroundColor: '#F8F7F4' }}>
<div className="container mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">

View File

@@ -4,13 +4,14 @@ import Link from 'next/link';
import Breadcrumbs, { BreadcrumbItem } from '@/components/Breadcrumbs';
import SeoJsonLd from '@/components/SeoJsonLd';
import { breadcrumbSchema } from '@/lib/schema';
import { FAQSection } from '@/components/aeo/FAQSection';
import { MarketingPageTracker, TrackedCtaLink } from '@/components/marketing/MarketingAnalytics';
import { Button } from '@/components/ui/Button';
import { Card } from '@/components/ui/Card';
export const metadata: Metadata = {
title: {
absolute: 'QR Code Platform Alternatives | QR Master',
absolute: 'QR Master Alternatives: Compare QR Code Platforms',
},
description:
'Compare QR Master with QR-Code-Generator.com, Flowcode, Beaconstac / Uniqode, and Bitly. Find the right QR alternative for pricing, branding, analytics, and bulk creation.',
@@ -18,7 +19,7 @@ export const metadata: Metadata = {
canonical: 'https://www.qrmaster.net/alternatives',
},
openGraph: {
title: 'QR Code Platform Alternatives | QR Master',
title: 'QR Master Alternatives: Compare QR Code Platforms',
description:
'Clean comparisons for the most common QR code platform alternatives, from pricing traps to branding limits and enterprise overkill.',
url: 'https://www.qrmaster.net/alternatives',
@@ -26,7 +27,7 @@ export const metadata: Metadata = {
images: ['/og-image.png'],
},
twitter: {
title: 'QR Code Platform Alternatives | QR Master',
title: 'QR Master Alternatives: Compare QR Code Platforms',
description:
'Compare QR Master with Flowcode, Bitly, Beaconstac / Uniqode, and QR-Code-Generator.com.',
},
@@ -46,6 +47,43 @@ const pageSchema = {
'Comparison pages for QR Master versus major QR code and adjacent link-management platforms.',
};
const faqItems = [
{
question: 'What is the best QR code platform alternative?',
answer:
'The best alternative depends on the workflow. QR Master is strongest when you need dynamic QR codes, clean branding, bulk creation, and privacy-friendly analytics without enterprise pricing.',
},
{
question: 'When should I choose QR Master over Bitly?',
answer:
'Choose QR Master when QR codes are the primary workflow. Bitly is useful for short links, but its QR code limits and link-first dashboard become restrictive for campaigns with many QR codes.',
},
{
question: 'When should I choose QR Master over Flowcode?',
answer:
'Choose QR Master when you want a direct scan experience without third-party branding or branded interstitial pages. QR Master keeps the scan flow focused on your destination.',
},
{
question: 'Is Beaconstac / Uniqode better than QR Master?',
answer:
'Beaconstac / Uniqode can make sense for enterprise teams that need a broad QR platform. QR Master is usually a better fit for smaller teams that want dynamic QR codes, analytics, and bulk creation at a simpler price point.',
},
];
const faqSchema = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
'@id': 'https://www.qrmaster.net/alternatives#faq',
mainEntity: faqItems.map((item) => ({
'@type': 'Question',
name: item.question,
acceptedAnswer: {
'@type': 'Answer',
text: item.answer,
},
})),
};
const alternativePages = [
{
href: '/alternatives/qr-code-generator',
@@ -77,10 +115,41 @@ const alternativePages = [
},
];
const comparisonRows = [
{
platform: 'Bitly',
href: '/alternatives/bitly',
bestFor: 'Short links and light QR use',
watchOut: 'Low QR code counts on entry plans; no bulk QR creation',
qrMasterAngle: 'QR-first workflow with 50 dynamic codes on Pro',
},
{
platform: 'Flowcode',
href: '/alternatives/flowcode',
bestFor: 'Design-forward QR campaigns',
watchOut: 'Branding and interstitial concerns on lower tiers',
qrMasterAngle: 'Clean redirects and brand control without a branded scan page',
},
{
platform: 'Beaconstac / Uniqode',
href: '/alternatives/beaconstac',
bestFor: 'Enterprise QR management',
watchOut: 'Often more platform than small teams need',
qrMasterAngle: 'Simpler dynamic QR, analytics, and bulk creation for SMB teams',
},
{
platform: 'QR-Code-Generator.com',
href: '/alternatives/qr-code-generator',
bestFor: 'Fast one-off QR creation',
watchOut: 'Dynamic QR trial limits can be painful after printing',
qrMasterAngle: 'Free dynamic codes and transparent paid tiers',
},
];
export default function AlternativesHubPage() {
return (
<>
<SeoJsonLd data={[pageSchema, breadcrumbSchema(breadcrumbItems)]} />
<SeoJsonLd data={[pageSchema, faqSchema, breadcrumbSchema(breadcrumbItems)]} />
<MarketingPageTracker pageType="commercial" cluster="competitor" />
<div className="min-h-screen" style={{ backgroundColor: '#F8F7F4', color: '#18181B' }}>
<section className="border-b bg-white" style={{ borderColor: '#E4E0D9' }}>
@@ -175,6 +244,56 @@ export default function AlternativesHubPage() {
</div>
</div>
</section>
<section className="border-y bg-white py-24" style={{ borderColor: '#E4E0D9' }}>
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="mb-12 max-w-3xl">
<h2 className="mb-4 text-3xl font-bold tracking-tight sm:text-4xl" style={{ color: '#111110' }}>
QR Master vs Bitly, Flowcode, Beaconstac and other QR platforms
</h2>
<p className="text-lg" style={{ color: '#71717A' }}>
Use this table to pick the comparison page that matches your search intent: pricing, branding, bulk
creation, analytics, or migration risk.
</p>
</div>
<div className="overflow-hidden rounded-xl border" style={{ borderColor: '#E4E0D9' }}>
<div className="grid grid-cols-1 md:grid-cols-5" style={{ backgroundColor: '#F8F7F4' }}>
{['Platform', 'Best for', 'Watch out for', 'QR Master angle', 'Compare'].map((heading) => (
<div key={heading} className="p-4 text-xs font-semibold uppercase tracking-wider" style={{ color: '#71717A' }}>
{heading}
</div>
))}
</div>
{comparisonRows.map((row, index) => (
<div
key={row.platform}
className="grid grid-cols-1 md:grid-cols-5"
style={{
borderTop: '1px solid #E4E0D9',
backgroundColor: index % 2 === 0 ? '#FFFFFF' : '#FAFAF8',
}}
>
<div className="p-4 font-semibold" style={{ color: '#18181B' }}>{row.platform}</div>
<div className="p-4 text-sm" style={{ color: '#52525B' }}>{row.bestFor}</div>
<div className="p-4 text-sm" style={{ color: '#52525B' }}>{row.watchOut}</div>
<div className="p-4 text-sm font-medium" style={{ color: '#166534' }}>{row.qrMasterAngle}</div>
<div className="p-4">
<Link href={row.href} className="text-sm font-semibold" style={{ color: '#166534' }}>
QR Master vs {row.platform}
</Link>
</div>
</div>
))}
</div>
</div>
</section>
<section className="py-24" style={{ backgroundColor: '#F8F7F4' }}>
<div className="container mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">
<FAQSection items={faqItems} title="Common questions about QR platform alternatives" />
</div>
</section>
</div>
</>
);

View File

@@ -27,9 +27,10 @@ export async function generateMetadata(): Promise<Metadata> {
'QR Master is a free QR code generator with scan analytics, dynamic QR codes, custom branding, and bulk creation. No signup required for static codes.',
160
);
const brandTitle = 'QR Master | Free Dynamic QR Code Generator';
return {
title,
title: brandTitle,
description,
keywords: [
'qr generator',
@@ -51,7 +52,7 @@ export async function generateMetadata(): Promise<Metadata> {
},
},
openGraph: {
title,
title: brandTitle,
description,
url: 'https://www.qrmaster.net/',
type: 'website',
@@ -65,7 +66,7 @@ export async function generateMetadata(): Promise<Metadata> {
],
},
twitter: {
title,
title: brandTitle,
description,
},
};
@@ -118,6 +119,13 @@ export default function HomePage() {
Upgrade to Pro for 50 codes with advanced analytics, or Business for
500 codes with bulk creation and priority support.
</p>
<p>
Frequently used QR Master tools and industry workflows include the{' '}
<a href="/tools/teams-qr-code">Teams QR code generator</a>,{' '}
<a href="/tools/wifi-qr-code">WiFi QR code generator</a>,{' '}
<a href="/qr-code-erstellen">German QR code generator</a>, and{' '}
<a href="/qr-code-for/barbershops">QR codes for barbershops</a>.
</p>
</div>
<HomePageClient />

View File

@@ -133,6 +133,8 @@ const highlightedLinks = [
{ href: "/qr-code-tracking", title: "QR Code Tracking", description: "Measure scans from flyers, property signage, retail displays, trade shows, and offline campaigns." },
{ href: "/bulk-qr-code-generator", title: "Bulk QR Code Generator", description: "Best fit for packaging, product lines, multi-location rollouts, and large campaigns." },
{ href: "/tools/wifi-qr-code", title: "WiFi QR Code Tool", description: "Popular for hotels, cafes, coworking spaces, clinics, and guest-facing venues." },
{ href: "/tools/teams-qr-code", title: "Teams QR Code Tool", description: "Useful for offices, meeting rooms, coworking spaces, and event check-in workflows." },
{ href: "/qr-code-for/barbershops", title: "QR Codes for Barbershops", description: "A high-intent local service page for bookings, reviews, WiFi, and social profile QR codes." },
];
export const metadata: Metadata = {
@@ -244,7 +246,7 @@ export default function IndustryOverviewPage() {
<section className="py-16">
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="grid gap-6 lg:grid-cols-4">
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
{highlightedLinks.map((item) => (
<Link
key={item.href}

View File

@@ -205,10 +205,66 @@ export default function UseCasesHubPage() {
))}
</div>
</div>
</section>
<section className="bg-slate-50 py-16">
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
</section>
<section className="bg-white py-16">
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="mb-8 max-w-3xl">
<div className="text-sm font-semibold uppercase tracking-[0.22em] text-blue-700">
Industry pages with early traction
</div>
<h2 className="mt-3 text-3xl font-bold text-slate-900">
Service business QR workflows
</h2>
<p className="mt-4 text-lg leading-8 text-slate-600">
These industry routes connect practical use cases with the QR
tools local businesses usually need first.
</p>
</div>
<div className="grid gap-4 md:grid-cols-3">
{[
{
href: "/qr-code-for/barbershops",
title: "QR Codes for Barbershops",
description:
"Booking links, review prompts, WiFi access, and social profiles for barbershop visits.",
},
{
href: "/tools/wifi-qr-code",
title: "WiFi QR Code Generator",
description:
"A practical guest-facing QR tool for service businesses and venues.",
},
{
href: "/qr-code-erstellen",
title: "QR Code Erstellen",
description:
"German QR creation page for local business owners who search in German.",
},
].map((item) => (
<Link
key={item.href}
href={item.href}
className="rounded-2xl border border-slate-200 bg-slate-50 p-6 transition-colors hover:border-blue-200 hover:bg-blue-50/70"
>
<h3 className="text-xl font-bold text-slate-900">
{item.title}
</h3>
<p className="mt-3 text-sm leading-6 text-slate-600">
{item.description}
</p>
<div className="mt-5 inline-flex items-center text-sm font-semibold text-blue-700">
Open page <ArrowRight className="ml-2 h-4 w-4" />
</div>
</Link>
))}
</div>
</div>
</section>
<section className="bg-slate-50 py-16">
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="grid gap-8 lg:grid-cols-[minmax(0,1fr)_minmax(0,0.95fr)]">
<Card className="rounded-3xl border-slate-200 bg-white p-8 shadow-sm">
<div className="flex items-center gap-3">

View File

@@ -1,5 +1,6 @@
import React from 'react';
import type { Metadata } from 'next';
import Link from 'next/link';
import { FreeToolsGrid } from '@/components/marketing/FreeToolsGrid';
export const metadata: Metadata = {
@@ -41,6 +42,50 @@ export default function ToolsHubPage() {
<FreeToolsGrid />
</div>
<section className="bg-white px-4 py-16">
<div className="container mx-auto max-w-5xl">
<div className="mb-8 text-center">
<h2 className="text-2xl font-bold text-slate-900">
Frequently used QR tools
</h2>
<p className="mx-auto mt-3 max-w-2xl text-slate-600">
These tools cover common workplace, venue, and regional QR code
workflows.
</p>
</div>
<div className="grid gap-4 md:grid-cols-3">
{[
{
href: '/tools/teams-qr-code',
title: 'Teams QR Code Generator',
description: 'Create QR codes for meeting rooms and invites.',
},
{
href: '/tools/wifi-qr-code',
title: 'WiFi QR Code Generator',
description: 'Share guest WiFi without typing passwords.',
},
{
href: '/qr-code-erstellen',
title: 'QR Code Erstellen',
description: 'German QR generator page for local users.',
},
].map((item) => (
<Link
key={item.href}
href={item.href}
className="rounded-lg border border-slate-200 bg-slate-50 p-5 text-left transition-colors hover:border-indigo-200 hover:bg-indigo-50"
>
<h3 className="font-semibold text-slate-900">{item.title}</h3>
<p className="mt-2 text-sm leading-6 text-slate-600">
{item.description}
</p>
</Link>
))}
</div>
</div>
</section>
<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">

View File

@@ -1,7 +1,8 @@
'use client';
import React from 'react';
import { Hero } from '@/components/marketing/Hero';
import React from 'react';
import Link from 'next/link';
import { Hero } from '@/components/marketing/Hero';
import AIComingSoonBanner from '@/components/marketing/AIComingSoonBanner';
import { StatsStrip } from '@/components/marketing/StatsStrip';
import { TemplateCards } from '@/components/marketing/TemplateCards';
@@ -40,10 +41,61 @@ export default function HomePageClient() {
<AIComingSoonBanner />
{/* Free Tools Grid */}
<FreeToolsGrid />
{/* Testimonials Carousel */}
{/* Free Tools Grid */}
<FreeToolsGrid />
<section className="bg-white py-16">
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="mb-8 max-w-3xl">
<h2 className="text-3xl font-bold text-slate-900">
Popular QR Master workflows
</h2>
<p className="mt-3 text-base leading-7 text-slate-600">
Start with the pages people already use for meetings, guest WiFi,
German QR creation, and local service businesses.
</p>
</div>
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
{[
{
href: '/tools/teams-qr-code',
title: 'Teams QR Code Generator',
description: 'Create a QR code for Microsoft Teams meetings.',
},
{
href: '/tools/wifi-qr-code',
title: 'WiFi QR Code Generator',
description: 'Let guests scan once to join a WiFi network.',
},
{
href: '/qr-code-erstellen',
title: 'QR Code Erstellen',
description: 'German QR code generator page for local searches.',
},
{
href: '/qr-code-for/barbershops',
title: 'QR Codes for Barbershops',
description: 'Booking, reviews, WiFi, and social links for shops.',
},
].map((item) => (
<Link
key={item.href}
href={item.href}
className="group rounded-lg border border-slate-200 bg-slate-50 p-5 transition-colors hover:border-blue-200 hover:bg-blue-50"
>
<h3 className="text-lg font-semibold text-slate-900 group-hover:text-blue-700">
{item.title}
</h3>
<p className="mt-2 text-sm leading-6 text-slate-600">
{item.description}
</p>
</Link>
))}
</div>
</div>
</section>
{/* Testimonials Carousel */}
<TestimonialsCarousel testimonials={testimonials} />
<React.Fragment>

View File

@@ -122,7 +122,7 @@ export function Footer({ variant = 'marketing', t }: FooterProps) {
<li><Link href="/privacy" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>{translations.privacy_policy}</Link></li>
<li><Link href="/contact" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Contact</Link></li>
<li><Link href="/qr-code-erstellen" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>QR Code Erstellen (DE)</Link></li>
<li><Link href="/barcode-generator" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Barcode Generator (DE)</Link></li>
<li><Link href="/tools/barcode-generator" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Barcode Generator</Link></li>
</ul>
</div>

View File

@@ -22,7 +22,7 @@
},
"hero": {
"badge": "Free QR Code Generator",
"title": "Create QR Codes That Work Everywhere",
"title": "QR Master: Create QR Codes That Work Everywhere",
"subtitle": "Generate static and dynamic QR codes with tracking, custom branding, and bulk generation. Free forever.",
"features": [
"No credit card required to start",

View File

@@ -398,6 +398,8 @@ export const blogPosts: BlogPost[] = [
<li><strong>Link too long to encode cleanly:</strong> Teams join URLs are long. Use a dynamic QR code — it encodes a short redirect URL instead, which produces a less dense, more reliably scannable code.</li>
</ul>
<p>Setting up QR codes for an office or venue? Pair Teams meeting access with a <a href="/tools/wifi-qr-code" class="text-blue-600 underline">WiFi QR code</a>, or use the German <a href="/qr-code-erstellen" class="text-blue-600 underline">QR Code Erstellen</a> page for local teams.</p>
<p>Ready to create yours? The <a href="/tools/teams-qr-code" class="text-blue-600 underline font-semibold">Teams QR code generator is free and takes under 60 seconds →</a></p>
</div>`,

View File

@@ -30,9 +30,9 @@ export function organizationSchema() {
'@context': 'https://schema.org',
'@type': 'Organization',
'@id': `${SITE_URL}/#organization`,
name: 'QR Master',
alternateName: 'QRMaster',
url: SITE_URL,
name: 'QR Master',
alternateName: ['QRMaster', 'QR Master QR Code Generator'],
url: SITE_URL,
logo: {
'@type': 'ImageObject',
url: `${SITE_URL}/static/og-image.png`,

View File

@@ -41,9 +41,18 @@ function attachAttributionCookie(req: NextRequest, response: NextResponse) {
return response;
}
export function middleware(req: NextRequest) {
const path = req.nextUrl.pathname;
export function middleware(req: NextRequest) {
const path = req.nextUrl.pathname;
const hostname = req.headers.get('host')?.split(':')[0] || req.nextUrl.hostname;
if (hostname === 'qrmaster.net') {
const url = req.nextUrl.clone();
url.protocol = 'https';
url.port = '';
url.hostname = 'www.qrmaster.net';
return NextResponse.redirect(url, 301);
}
// 301 Redirects for /guide -> /learn to avoid duplicate content and consolidate authority
if (path === '/guide/tracking-analytics') {
return attachAttributionCookie(req, NextResponse.redirect(new URL('/learn/tracking', req.url), 301));
@@ -57,9 +66,12 @@ export function middleware(req: NextRequest) {
if (path === '/create-qr') {
return attachAttributionCookie(req, NextResponse.redirect(new URL('/dynamic-qr-code-generator', req.url), 301));
}
// Public routes that don't require authentication
const publicPaths = [
if (path === '/bar-code-generator' || path === '/barcode-generator') {
return attachAttributionCookie(req, NextResponse.redirect(new URL('/tools/barcode-generator', req.url), 301));
}
// Public routes that don't require authentication
const publicPaths = [
'/',
'/pricing',
'/faq',
@@ -78,10 +90,9 @@ export function middleware(req: NextRequest) {
'/bulk-qr-code-generator',
'/qr-code-tracking',
'/qr-code-analytics',
'/reprint-calculator',
'/barcode-generator',
'/custom-qr-code-generator',
'/manage-qr-codes',
'/reprint-calculator',
'/custom-qr-code-generator',
'/manage-qr-codes',
'/coupon',
'/feedback',
'/vcard',
@@ -124,13 +135,29 @@ export function middleware(req: NextRequest) {
return attachAttributionCookie(req, NextResponse.next());
}
// Allow public paths
// Allow public paths
if (isPublicPath) {
return attachAttributionCookie(req, NextResponse.next());
}
// For protected routes, check for userId cookie
const userId = req.cookies.get('userId')?.value;
const protectedPaths = [
'/analytics',
'/bulk-creation',
'/create',
'/dashboard',
'/integrations',
'/onboarding',
'/qr',
'/settings',
];
const isProtectedPath = protectedPaths.some(p => path === p || path.startsWith(p + '/'));
if (!isProtectedPath) {
return attachAttributionCookie(req, NextResponse.next());
}
// For protected routes, check for userId cookie
const userId = req.cookies.get('userId')?.value;
if (!userId) {
// Not authenticated - redirect to signup