feat: implement marketing comparison and alternatives hub with dedicated competitor landing pages
This commit is contained in:
181
src/app/(main)/(marketing)/alternatives/page.tsx
Normal file
181
src/app/(main)/(marketing)/alternatives/page.tsx
Normal file
@@ -0,0 +1,181 @@
|
||||
import React from 'react';
|
||||
import type { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import Breadcrumbs, { BreadcrumbItem } from '@/components/Breadcrumbs';
|
||||
import SeoJsonLd from '@/components/SeoJsonLd';
|
||||
import { breadcrumbSchema } from '@/lib/schema';
|
||||
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',
|
||||
},
|
||||
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.',
|
||||
alternates: {
|
||||
canonical: 'https://www.qrmaster.net/alternatives',
|
||||
},
|
||||
openGraph: {
|
||||
title: 'QR Code Platform Alternatives | QR Master',
|
||||
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',
|
||||
type: 'website',
|
||||
images: ['/og-image.png'],
|
||||
},
|
||||
twitter: {
|
||||
title: 'QR Code Platform Alternatives | QR Master',
|
||||
description:
|
||||
'Compare QR Master with Flowcode, Bitly, Beaconstac / Uniqode, and QR-Code-Generator.com.',
|
||||
},
|
||||
};
|
||||
|
||||
const breadcrumbItems: BreadcrumbItem[] = [
|
||||
{ name: 'Home', url: '/' },
|
||||
{ name: 'Alternatives', url: '/alternatives' },
|
||||
];
|
||||
|
||||
const pageSchema = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'CollectionPage',
|
||||
name: 'QR Code Platform Alternatives',
|
||||
url: 'https://www.qrmaster.net/alternatives',
|
||||
description:
|
||||
'Comparison pages for QR Master versus major QR code and adjacent link-management platforms.',
|
||||
};
|
||||
|
||||
const alternativePages = [
|
||||
{
|
||||
href: '/alternatives/qr-code-generator',
|
||||
eyebrow: 'Trial trap',
|
||||
title: 'QR-Code-Generator.com Alternative',
|
||||
description:
|
||||
'For teams burned by 14-day dynamic QR trials and forced annual upgrades after print is already live.',
|
||||
},
|
||||
{
|
||||
href: '/alternatives/flowcode',
|
||||
eyebrow: 'Brand control',
|
||||
title: 'Flowcode Alternative',
|
||||
description:
|
||||
'For brands and agencies that need clean QR codes without third-party logos or branded scan interstitials.',
|
||||
},
|
||||
{
|
||||
href: '/alternatives/beaconstac',
|
||||
eyebrow: 'SMB fit',
|
||||
title: 'Beaconstac / Uniqode Alternative',
|
||||
description:
|
||||
'For smaller teams that want reliable analytics and bulk QR creation without paying enterprise-platform pricing.',
|
||||
},
|
||||
{
|
||||
href: '/alternatives/bitly',
|
||||
eyebrow: 'QR-first workflow',
|
||||
title: 'Bitly Alternative',
|
||||
description:
|
||||
'For campaigns where QR codes are the main workflow, not a side feature hidden inside a link shortener.',
|
||||
},
|
||||
];
|
||||
|
||||
export default function AlternativesHubPage() {
|
||||
return (
|
||||
<>
|
||||
<SeoJsonLd data={[pageSchema, 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' }}>
|
||||
<div className="container mx-auto max-w-7xl px-4 pb-20 pt-10 sm:px-6 lg:px-8">
|
||||
<div className="mb-10">
|
||||
<Breadcrumbs items={breadcrumbItems} />
|
||||
</div>
|
||||
|
||||
<div className="max-w-3xl">
|
||||
<div
|
||||
className="mb-6 inline-block rounded px-3 py-1.5 text-xs font-semibold uppercase tracking-widest"
|
||||
style={{ backgroundColor: '#DCFCE7', color: '#166534', letterSpacing: '0.12em' }}
|
||||
>
|
||||
QR Master alternatives
|
||||
</div>
|
||||
<h1
|
||||
className="mb-6 text-4xl font-extrabold leading-[1.08] tracking-tight sm:text-5xl"
|
||||
style={{ color: '#111110' }}
|
||||
>
|
||||
Clean comparisons for the QR platforms people actually switch from.
|
||||
</h1>
|
||||
<p className="mb-8 text-lg leading-relaxed" style={{ color: '#52525B' }}>
|
||||
Some tools hide trial limits. Some force their brand into your scan flow. Some are simply priced for
|
||||
enterprise teams. These pages break down where each platform fits, where it does not, and when QR
|
||||
Master is the better tradeoff.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col gap-3 sm:flex-row">
|
||||
<TrackedCtaLink
|
||||
href="/signup"
|
||||
ctaLabel="Start Free"
|
||||
ctaLocation="hero_primary"
|
||||
pageType="commercial"
|
||||
cluster="competitor"
|
||||
>
|
||||
<Button size="lg" className="h-13 w-full px-8 text-base sm:w-auto">
|
||||
Start Free
|
||||
</Button>
|
||||
</TrackedCtaLink>
|
||||
<TrackedCtaLink
|
||||
href="/pricing"
|
||||
ctaLabel="See Pricing"
|
||||
ctaLocation="hero_secondary"
|
||||
pageType="commercial"
|
||||
cluster="competitor"
|
||||
>
|
||||
<Button variant="outline" size="lg" className="h-13 w-full px-8 text-base sm:w-auto">
|
||||
See Pricing
|
||||
</Button>
|
||||
</TrackedCtaLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="py-24" style={{ backgroundColor: '#F8F7F4' }}>
|
||||
<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' }}>
|
||||
Explore Alternatives
|
||||
</h2>
|
||||
<p className="text-lg" style={{ color: '#71717A' }}>
|
||||
Pick the comparison that matches the problem you are trying to solve.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-2 xl:grid-cols-4">
|
||||
{alternativePages.map((item) => (
|
||||
<Link key={item.href} href={item.href} className="group block">
|
||||
<Card
|
||||
className="h-full rounded-xl border bg-white p-7 shadow-none transition-transform duration-150 group-hover:-translate-y-1"
|
||||
style={{ borderColor: '#E4E0D9' }}
|
||||
>
|
||||
<p
|
||||
className="mb-4 text-xs font-semibold uppercase tracking-widest"
|
||||
style={{ color: '#71717A', letterSpacing: '0.12em' }}
|
||||
>
|
||||
{item.eyebrow}
|
||||
</p>
|
||||
<h3 className="mb-3 text-xl font-bold" style={{ color: '#18181B' }}>
|
||||
{item.title}
|
||||
</h3>
|
||||
<p className="text-sm leading-relaxed" style={{ color: '#52525B' }}>
|
||||
{item.description}
|
||||
</p>
|
||||
<p className="mt-6 text-sm font-semibold" style={{ color: '#166534' }}>
|
||||
Open comparison
|
||||
</p>
|
||||
</Card>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user