Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
567 changes: 567 additions & 0 deletions src/app/compare/onfleet-alternative-pages.tsx

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions src/app/compare/onfleet-api-platform-alternative/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { getOnfleetAlternativePage, OnfleetAlternativeLanding } from '../onfleet-alternative-pages';

const page = getOnfleetAlternativePage('onfleet-api-platform-alternative');

export const metadata = page.metadata;

export default function OnfleetApiPlatformAlternativePage() {
return <OnfleetAlternativeLanding page={page} />;
}
9 changes: 9 additions & 0 deletions src/app/compare/onfleet-dispatch-alternative/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { getOnfleetAlternativePage, OnfleetAlternativeLanding } from '../onfleet-alternative-pages';

const page = getOnfleetAlternativePage('onfleet-dispatch-alternative');

export const metadata = page.metadata;

export default function OnfleetDispatchAlternativePage() {
return <OnfleetAlternativeLanding page={page} />;
}
9 changes: 9 additions & 0 deletions src/app/compare/onfleet-driver-app-pod-alternative/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { getOnfleetAlternativePage, OnfleetAlternativeLanding } from '../onfleet-alternative-pages';

const page = getOnfleetAlternativePage('onfleet-driver-app-pod-alternative');

export const metadata = page.metadata;

export default function OnfleetDriverAppPodAlternativePage() {
return <OnfleetAlternativeLanding page={page} />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { getOnfleetAlternativePage, OnfleetAlternativeLanding } from '../onfleet-alternative-pages';

const page = getOnfleetAlternativePage('onfleet-route-optimization-alternative');

export const metadata = page.metadata;

export default function OnfleetRouteOptimizationAlternativePage() {
return <OnfleetAlternativeLanding page={page} />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { getOnfleetAlternativePage, OnfleetAlternativeLanding } from '../onfleet-alternative-pages';

const page = getOnfleetAlternativePage('onfleet-tracking-notifications-alternative');

export const metadata = page.metadata;

export default function OnfleetTrackingNotificationsAlternativePage() {
return <OnfleetAlternativeLanding page={page} />;
}
38 changes: 37 additions & 1 deletion src/app/compare/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { ArrowRight } from 'lucide-react';
import type { Metadata } from 'next';
import Link from 'next/link';
import { ArrowRight } from 'lucide-react';

import { Button } from '@/components/ui/button';

import { ONFLEET_ALTERNATIVE_PAGES } from './onfleet-alternative-pages';

export const metadata: Metadata = {
title: 'Fleetbase Comparisons | Open-Source Alternative to Onfleet, Tookan, Route4Me',
description:
Expand Down Expand Up @@ -97,6 +100,39 @@ export default function ComparePage() {
</div>
</section>

{/* Onfleet Alternative Landing Pages */}
<section className="py-16 md:py-20 border-t bg-muted/20">
<div className="container max-w-5xl">
<div className="mb-10 max-w-2xl">
<p className="mb-3 text-xs font-semibold uppercase tracking-widest text-primary">Onfleet alternatives</p>
<h2 className="text-3xl font-bold tracking-tight md:text-4xl">
Win the specific comparison your buyer is already making
</h2>
<p className="mt-4 text-muted-foreground">
Focused pages for teams searching for a lower-cost, more controllable alternative to individual Onfleet capabilities.
</p>
</div>
<div className="grid gap-4 md:grid-cols-2">
{ONFLEET_ALTERNATIVE_PAGES.map((item) => (
<Link
key={item.slug}
href={`/compare/${item.slug}`}
className="group rounded-xl border bg-card p-5 transition-all hover:border-primary/50 hover:shadow-md"
>
<div className="mb-2 flex items-start justify-between gap-4">
<div>
<p className="text-xs font-medium text-primary">{item.eyebrow}</p>
<h3 className="mt-1 text-lg font-semibold tracking-tight">{item.title}</h3>
</div>
<ArrowRight className="mt-1 h-5 w-5 shrink-0 text-muted-foreground transition-all group-hover:translate-x-1 group-hover:text-primary" />
</div>
<p className="text-sm leading-relaxed text-muted-foreground">{item.description}</p>
</Link>
))}
</div>
</div>
</section>

{/* Bottom CTA */}
<section className="py-16 border-t bg-muted/20">
<div className="container max-w-3xl text-center space-y-6">
Expand Down
5 changes: 5 additions & 0 deletions src/app/sitemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ const STATIC_ROUTES: StaticEntry[] = [
// Compare
{ path: '/compare', changeFrequency: 'monthly', priority: 0.8 },
{ path: '/compare/vs-onfleet', changeFrequency: 'monthly', priority: 0.9 },
{ path: '/compare/onfleet-route-optimization-alternative', changeFrequency: 'monthly', priority: 0.85 },
{ path: '/compare/onfleet-dispatch-alternative', changeFrequency: 'monthly', priority: 0.85 },
{ path: '/compare/onfleet-tracking-notifications-alternative', changeFrequency: 'monthly', priority: 0.85 },
{ path: '/compare/onfleet-driver-app-pod-alternative', changeFrequency: 'monthly', priority: 0.85 },
{ path: '/compare/onfleet-api-platform-alternative', changeFrequency: 'monthly', priority: 0.85 },
{ path: '/compare/vs-route4me', changeFrequency: 'monthly', priority: 0.8 },
{ path: '/compare/vs-tookan', changeFrequency: 'monthly', priority: 0.9 },

Expand Down
16 changes: 15 additions & 1 deletion src/components/layout/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,14 @@ const SOCIAL_LINKS = [
},
];

const FOOTER_LINKS = [
type FooterLink = { label: string; href: string; external?: boolean } | { subheading: string };

type FooterSection = {
title: string;
links: FooterLink[];
};

const FOOTER_LINKS: FooterSection[] = [
{
title: 'Platform',
links: [
Expand Down Expand Up @@ -70,6 +77,13 @@ const FOOTER_LINKS = [
links: [
{ label: 'All Comparisons', href: '/compare' },
{ label: 'Fleetbase vs Onfleet', href: '/compare/vs-onfleet' },
{ subheading: 'Onfleet Alternatives' },
{ label: 'Route Optimization', href: '/compare/onfleet-route-optimization-alternative' },
{ label: 'Dispatch Automation', href: '/compare/onfleet-dispatch-alternative' },
{ label: 'Tracking & Notifications', href: '/compare/onfleet-tracking-notifications-alternative' },
{ label: 'Driver App & POD', href: '/compare/onfleet-driver-app-pod-alternative' },
{ label: 'API & Platform', href: '/compare/onfleet-api-platform-alternative' },
{ subheading: 'Other Comparisons' },
{ label: 'Fleetbase vs Tookan', href: '/compare/vs-tookan' },
{ label: 'Fleetbase vs Route4Me', href: '/compare/vs-route4me' },
{ subheading: 'Powered by Fleetbase' },
Expand Down