fix: add internal links
This commit is contained in:
@@ -78,6 +78,8 @@ export default async function Page({
|
||||
'@type': 'Article',
|
||||
headline: article?.data.title,
|
||||
datePublished: article?.data.date.toISOString(),
|
||||
dateModified:
|
||||
article?.data.updated?.toISOString() || article?.data.date.toISOString(),
|
||||
author: {
|
||||
'@type': 'Person',
|
||||
name: author.name,
|
||||
@@ -132,9 +134,16 @@ export default async function Page({
|
||||
</div>
|
||||
<div className="col">
|
||||
<p className="font-medium">{author.name}</p>
|
||||
<p className="text-muted-foreground text-sm">
|
||||
{article?.data.date.toLocaleDateString()}
|
||||
</p>
|
||||
<div className="row gap-2">
|
||||
<p className="text-muted-foreground text-sm">
|
||||
{article?.data.date.toLocaleDateString()}
|
||||
</p>
|
||||
{article?.data.updated && (
|
||||
<p className="text-muted-foreground text-sm italic">
|
||||
Updated on {article?.data.updated.toLocaleDateString()}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
import { FeatureCardContainer } from '@/components/feature-card';
|
||||
import { Section, SectionHeader } from '@/components/section';
|
||||
import type { RelatedLinks } from '@/lib/compare';
|
||||
import { ArrowRightIcon, BookOpenIcon, GitCompareIcon } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
|
||||
interface RelatedLinksProps {
|
||||
relatedLinks?: RelatedLinks;
|
||||
}
|
||||
|
||||
export function RelatedLinksSection({ relatedLinks }: RelatedLinksProps) {
|
||||
if (
|
||||
!relatedLinks ||
|
||||
(!relatedLinks.articles?.length && !relatedLinks.alternatives?.length)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Section className="container">
|
||||
<SectionHeader
|
||||
title="Related resources"
|
||||
description="Explore more comparisons and guides to help you choose the right analytics tool"
|
||||
variant="sm"
|
||||
/>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mt-12">
|
||||
{relatedLinks.articles && relatedLinks.articles.length > 0 && (
|
||||
<div className="col gap-4">
|
||||
<div className="row gap-2 items-center mb-2">
|
||||
<BookOpenIcon className="size-5 text-muted-foreground" />
|
||||
<h3 className="text-lg font-semibold">Articles</h3>
|
||||
</div>
|
||||
<div className="col gap-3">
|
||||
{relatedLinks.articles.map((article) => (
|
||||
<Link key={article.url} href={article.url}>
|
||||
<FeatureCardContainer className="hover:border-primary/30 transition-colors">
|
||||
<div className="row gap-3 items-center">
|
||||
<div className="col gap-1 flex-1 min-w-0">
|
||||
<h4 className="text-base font-semibold group-hover:text-primary transition-colors">
|
||||
{article.title}
|
||||
</h4>
|
||||
</div>
|
||||
<ArrowRightIcon className="opacity-0 group-hover:opacity-100 size-4 shrink-0 text-muted-foreground group-hover:text-primary group-hover:translate-x-1 transition-all duration-300" />
|
||||
</div>
|
||||
</FeatureCardContainer>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{relatedLinks.alternatives && relatedLinks.alternatives.length > 0 && (
|
||||
<div className="col gap-4">
|
||||
<div className="row gap-2 items-center mb-2">
|
||||
<GitCompareIcon className="size-5 text-muted-foreground" />
|
||||
<h3 className="text-lg font-semibold">Other comparisons</h3>
|
||||
</div>
|
||||
<div className="col gap-3">
|
||||
{relatedLinks.alternatives.map((alternative) => (
|
||||
<Link key={alternative.url} href={alternative.url}>
|
||||
<FeatureCardContainer className="hover:border-primary/30 transition-colors">
|
||||
<div className="row gap-3 items-center">
|
||||
<div className="col gap-1 flex-1 min-w-0">
|
||||
<h4 className="text-base font-semibold group-hover:text-primary transition-colors">
|
||||
{alternative.name} alternative
|
||||
</h4>
|
||||
</div>
|
||||
<ArrowRightIcon className="opacity-0 group-hover:opacity-100 size-4 shrink-0 text-muted-foreground group-hover:text-primary group-hover:translate-x-1 transition-all duration-300" />
|
||||
</div>
|
||||
</FeatureCardContainer>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import { ComparisonTable } from './_components/comparison-table';
|
||||
import { FeaturesShowcase } from './_components/features-showcase';
|
||||
import { MigrationSection } from './_components/migration-section';
|
||||
import { PricingSection } from './_components/pricing-section';
|
||||
import { RelatedLinksSection } from './_components/related-links';
|
||||
import { TechnicalComparison } from './_components/technical-comparison';
|
||||
import { UseCases } from './_components/use-cases';
|
||||
import { WhoShouldChoose } from './_components/who-should-choose';
|
||||
@@ -213,6 +214,10 @@ export default async function ComparePage({
|
||||
<CompareFaq faqs={data.faqs} pageUrl={pageUrl} />
|
||||
</div>
|
||||
|
||||
{data.related_links && (
|
||||
<RelatedLinksSection relatedLinks={data.related_links} />
|
||||
)}
|
||||
|
||||
<CtaBanner
|
||||
title={'Ready to make the switch?'}
|
||||
description="Test OpenPanel free for 30 days, you'll not be charged anything unless you upgrade to a paid plan."
|
||||
|
||||
@@ -9,6 +9,7 @@ import { getOgImageUrl, getPageMetadata } from '@/lib/metadata';
|
||||
import { formatEventsCount } from '@/lib/utils';
|
||||
import { PRICING } from '@openpanel/payments/prices';
|
||||
import type { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import Script from 'next/script';
|
||||
|
||||
const title = 'OpenPanel Cloud Pricing';
|
||||
@@ -58,6 +59,7 @@ export default function SupporterPage() {
|
||||
</HeroContainer>
|
||||
<Pricing />
|
||||
<PricingTable />
|
||||
<ComparisonSection />
|
||||
<Testimonials />
|
||||
<Faq />
|
||||
<CtaBanner />
|
||||
@@ -107,3 +109,25 @@ function PricingTable() {
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
|
||||
function ComparisonSection() {
|
||||
return (
|
||||
<Section className="container">
|
||||
<SectionHeader
|
||||
title="How do we compare?"
|
||||
description={
|
||||
<>
|
||||
See how OpenPanel stacks up against other analytics tools in our{' '}
|
||||
<Link
|
||||
href="/articles/open-source-web-analytics"
|
||||
className="underline hover:text-primary transition-colors"
|
||||
>
|
||||
comprehensive comparison of open source web analytics tools
|
||||
</Link>
|
||||
.
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ const faqData = [
|
||||
{
|
||||
question: 'How does OpenPanel compare to other analytics tools?',
|
||||
answer:
|
||||
'We have a dedicated compare page where you can see how OpenPanel compares to other analytics tools. You can find it [here](/compare).',
|
||||
'We have a dedicated compare page where you can see how OpenPanel compares to other analytics tools. You can find it [here](/compare). You can also read our comprehensive guide on the [best open source web analytics tools](/articles/open-source-web-analytics).',
|
||||
},
|
||||
{
|
||||
question: 'How does OpenPanel compare to Mixpanel?',
|
||||
|
||||
Reference in New Issue
Block a user