Skip to content
Merged
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
117 changes: 109 additions & 8 deletions app/(marketing)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import Link from "next/link";
import { HeroAuditForm } from "@/components/hero-audit-form";
import { OrganizationJsonLd, SoftwareApplicationJsonLd, FaqJsonLd } from "@/components/json-ld";
import { PerformancePreview } from "@/components/report/performance-preview";
import { UptimePreview } from "@/components/report/uptime-preview";
import { SecurityPreview } from "@/components/report/security-preview";
import { env } from "@/lib/env";

const faqs = [
Expand All @@ -17,6 +19,14 @@ const faqs = [
q: "Do you respect robots.txt?",
a: "Yes. CrawlProofBot identifies itself and honors robots.txt directives that block it. We never log in, never submit forms, never POST.",
},
{
q: "What can CrawlProof monitor for uptime?",
a: "HTTP(S) status and response time, a keyword that must appear (or not) in the page body, SSL-certificate expiry, and raw TCP ports. We confirm failures across multiple checks before alerting (no flapping), then email you on both downtime and recovery — with the exact outage duration.",
},
{
q: "How does the exposed-services security scan work?",
a: "For hosts you've verified you own, CrawlProof runs a full 65,535-port TCP scan from a dedicated scanner, baselines the ports you expect to be open, and alerts you when a new one appears — e.g. a database or admin port suddenly reachable from the public internet. It's attack-surface drift detection, only ever against your own verified hosts.",
},
{
q: "Is the free tier really free?",
a: "Yes — anonymous visitors get 10 audits per day per IP with no signup, and signing up unlocks 20 free credits (1 AI-model scan). Paid scans cost 20 credits (~$1) with volume discounts down to $0.50/scan at the 100-scan pack. No subscription, credits never expire.",
Expand All @@ -43,20 +53,21 @@ export default function HomePage() {

<section className="mx-auto max-w-4xl px-4 sm:px-6 pb-12 pt-12 sm:pb-16 sm:pt-20 text-center">
<p className="mb-3 text-sm font-medium uppercase tracking-wider text-[var(--color-accent)]">
SEO · AEO · GEO — ChatGPT · Claude · Perplexity · Google AI Overviews
Audits · Uptime · Security · Content — one platform for your site
</p>
<h1 className="text-balance text-4xl font-extrabold leading-tight sm:text-5xl md:text-6xl">
See your site the way AI crawlers do.
Get found by AI. Stay online. Stay secure.
</h1>
<p className="mx-auto mt-5 max-w-2xl text-lg text-[var(--color-muted)]">
CrawlProof started by showing you your site the way{" "}
<strong className="font-semibold text-[var(--color-text)]">
AEO + GEO — Answer Engine &amp; Generative Engine Optimization
AI crawlers
</strong>{" "}
— making sure ChatGPT, Claude, Perplexity, and Google AI Overviews can
actually read, cite, and recommend your site. CrawlProof audits any
URL and shows you exactly what they find: content, schema, robots
rules, AI-bot access, llms.txt quality, knowledge graph anchoring, and
positioning.
do — SEO, AEO &amp; GEO audits for ChatGPT, Claude, Perplexity, and
Google AI Overviews. Now it&apos;s a full platform: <strong className="font-semibold text-[var(--color-text)]">uptime
monitoring</strong> with downtime alerts, <strong className="font-semibold text-[var(--color-text)]">exposed-services
security scans</strong>, automated content, backlinks, and analytics —
all from one dashboard. Start with a free audit:
</p>
<div className="mx-auto mt-8 max-w-xl">
<HeroAuditForm />
Expand All @@ -80,6 +91,24 @@ export default function HomePage() {
</div>
</section>

<section className="mx-auto max-w-6xl px-4 sm:px-6 pb-16">
<h2 className="mb-2 text-center text-2xl font-bold">One platform, every angle</h2>
<p className="mx-auto mb-8 max-w-2xl text-center text-sm text-[var(--color-muted)]">
Everything you need to get discovered, stay online, and stay secure — no
separate subscriptions for monitoring, security, and content.
</p>
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
<ModuleCard emoji="🔍" title="SEO · AEO · GEO Audits" body="See your site the way ChatGPT, Claude, Perplexity, and Google AI crawlers do — with a priority to-do list." />
<ModuleCard emoji="📈" title="Uptime Monitoring" body="HTTP, keyword, SSL &amp; TCP checks with instant down/recovery alerts to email, Slack, and Discord." />
<ModuleCard emoji="🛡️" title="Exposed Services" body="Full-port security scans of your verified hosts — get alerted the moment a database or admin port is exposed." />
<ModuleCard emoji="✍️" title="Autoblog" body="Research, draft, illustrate, and publish long-form SEO posts to your CMS on a schedule — ~$1 each." />
<ModuleCard emoji="🔗" title="Link Exchange" body="Verified backlink matching with a real ledger — quality links without four-figure marketplace prices." />
<ModuleCard emoji="📊" title="Analytics Tracker" body="A drop-in tracker for AI referrals, bot crawls, human traffic, pages, and geo — see who (and what) visits." />
<ModuleCard emoji="📣" title="Social Posting" body="Draft and schedule social posts and feed autoposts alongside your content pipeline." />
<ModuleCard emoji="🐙" title="GitHub Fixes" body="Bind a repo and turn audit findings into ready-to-merge pull requests." />
</div>
</section>

<section className="mx-auto max-w-6xl px-4 sm:px-6 pb-16">
<h2 className="mb-2 text-center text-2xl font-bold">What we check</h2>
<p className="mx-auto mb-8 max-w-2xl text-center text-sm text-[var(--color-muted)]">
Expand Down Expand Up @@ -132,6 +161,66 @@ export default function HomePage() {
<PerformancePreview variant="home" />
</section>

<section className="mx-auto max-w-6xl px-4 sm:px-6 pb-16">
<div className="grid items-center gap-8 lg:grid-cols-[1.05fr_0.95fr]">
<div>
<p className="mb-3 text-sm font-medium uppercase tracking-wider text-[var(--color-accent)]">
Uptime Monitoring
</p>
<h2 className="text-balance text-3xl font-extrabold leading-tight sm:text-4xl">
Know before your customers do.
</h2>
<p className="mt-4 text-[var(--color-muted)]">
Add a monitor in one click — we prefill your domain and URL. CrawlProof
checks it on your interval and emails you the instant it goes down,
then again when it recovers, with the exact downtime. HTTP status,
body keywords, SSL-cert expiry, and raw TCP ports.
</p>
<div className="mt-6 grid gap-3 sm:grid-cols-3">
<LaunchStat label="Checks" value="HTTP · SSL · TCP" />
<LaunchStat label="Alerts" value="Email · Slack" />
<LaunchStat label="Confirm" value="No flapping" />
</div>
<div className="mt-6 flex flex-wrap gap-3">
<Link href="/signup" className="btn btn-primary">
Start monitoring free
</Link>
</div>
</div>
<UptimePreview />
</div>
</section>

<section className="mx-auto max-w-6xl px-4 sm:px-6 pb-16">
<div className="grid items-center gap-8 lg:grid-cols-[0.95fr_1.05fr]">
<SecurityPreview />
<div>
<p className="mb-3 text-sm font-medium uppercase tracking-wider text-[var(--color-accent)]">
Exposed Services — Security
</p>
<h2 className="text-balance text-3xl font-extrabold leading-tight sm:text-4xl">
Catch the port you forgot to close.
</h2>
<p className="mt-4 text-[var(--color-muted)]">
CrawlProof runs a full 65,535-port scan of your owner-verified hosts,
baselines what&apos;s expected, and alerts you the moment something{" "}
<em>new</em> gets exposed — a Redis, a Postgres, an admin panel facing
the public internet. Attack-surface monitoring, not a one-off scan.
</p>
<div className="mt-6 grid gap-3 sm:grid-cols-3">
<LaunchStat label="Coverage" value="All 65,535" />
<LaunchStat label="Scope" value="Owned hosts" />
<LaunchStat label="Alerts on" value="Port drift" />
</div>
<div className="mt-6 flex flex-wrap gap-3">
<Link href="/signup" className="btn btn-primary">
Scan my services
</Link>
</div>
</div>
</div>
</section>

<section className="mx-auto max-w-6xl px-4 sm:px-6 pb-16">
<div className="grid items-center gap-8 lg:grid-cols-[0.95fr_1.05fr]">
<div>
Expand Down Expand Up @@ -275,3 +364,15 @@ function FeatureCard({ title, body }: { title: string; body: string }) {
</div>
);
}

function ModuleCard({ emoji, title, body }: { emoji: string; title: string; body: string }) {
return (
<div className="card flex flex-col p-5">
<div className="text-2xl" aria-hidden>
{emoji}
</div>
<h3 className="mt-2 font-semibold">{title}</h3>
<p className="mt-1 text-sm text-[var(--color-muted)]">{body}</p>
</div>
);
}
76 changes: 76 additions & 0 deletions components/report/security-preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Screenshot-style preview of the Security / Exposed Services tab for the
// marketing homepage. Coded panel (fixed dark chrome), matching the site's
// existing preview components.

const ports = [
{ port: 443, service: "https", sev: "low", isNew: false },
{ port: 80, service: "http", sev: "low", isNew: false },
{ port: 22, service: "ssh", sev: "medium", isNew: false },
{ port: 6379, service: "redis", sev: "high", isNew: true },
{ port: 5432, service: "postgres", sev: "high", isNew: true },
];

const SEV_COLOR: Record<string, string> = {
high: "#f87171",
medium: "#fbbf24",
low: "#6ee7b7",
};

export function SecurityPreview() {
return (
<div
className="rounded-xl border border-[var(--color-border)] bg-[#101820] p-5 shadow-2xl shadow-black/20 sm:p-6"
aria-label="Exposed services panel: a full port scan with two newly-exposed high-severity database ports."
>
<div className="flex items-center justify-between">
<div>
<div className="text-sm font-bold">Exposed Services</div>
<div className="font-mono text-xs text-[var(--color-muted)]">scan of acme.io</div>
</div>
<div className="rounded-full border border-[rgba(248,113,113,0.35)] bg-[rgba(248,113,113,0.12)] px-2.5 py-1 text-xs font-semibold text-[#f87171]">
2 new
</div>
</div>

<div className="mt-4 space-y-2">
{ports.map((p) => (
<div
key={p.port}
className="grid grid-cols-[auto_1fr_auto] items-center gap-3 rounded-lg bg-[#17202a] px-3 py-2.5"
>
<span
className="w-14 text-xs font-semibold uppercase"
style={{ color: SEV_COLOR[p.sev] }}
>
{p.sev}
</span>
<span className="font-mono text-sm">
acme.io:<span className="font-bold">{p.port}</span>{" "}
<span className="text-[var(--color-muted)]">({p.service})</span>
</span>
{p.isNew ? (
<span className="rounded bg-[rgba(248,113,113,0.15)] px-2 py-0.5 text-right text-xs font-semibold text-[#f87171]">
NEW
</span>
) : (
<span className="text-right text-xs text-[var(--color-muted)]">baseline</span>
)}
</div>
))}
</div>

<div className="mt-4 rounded-lg border border-[rgba(248,113,113,0.25)] bg-[rgba(248,113,113,0.08)] p-3 text-xs">
<span className="font-semibold text-[#f87171]">Port drift detected</span>
<span className="text-[var(--color-muted)]">
{" "}
· Redis &amp; Postgres now reachable from the public internet
</span>
</div>

<p className="mt-4 text-xs text-[var(--color-muted)]">
Full 65,535-port scan of your owner-verified hosts. We baseline what&apos;s
expected and alert only when something <em>new</em> gets exposed.
</p>
</div>
);
}
62 changes: 62 additions & 0 deletions components/report/uptime-preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Screenshot-style preview of the Uptime tab for the marketing homepage.
// Coded panel (fixed dark chrome) rather than a raster capture, matching the
// site's existing preview components.

const rows = [
{ name: "crawlproof.com", meta: "http · 60s", state: "up", latency: "142 ms" },
{ name: "api.crawlproof.com", meta: "http · /health", state: "up", latency: "88 ms" },
{ name: "db.acme.io:5432", meta: "tcp", state: "up", latency: "12 ms" },
{ name: "status.acme.io", meta: "http · 500", state: "down", latency: "—" },
];

export function UptimePreview() {
return (
<div
className="rounded-xl border border-[var(--color-border)] bg-[#101820] p-5 shadow-2xl shadow-black/20 sm:p-6"
aria-label="Uptime monitors panel: three monitors up, one down, with an open incident."
>
<div className="flex items-center justify-between">
<div className="text-sm font-bold">Uptime Monitors</div>
<div className="rounded-full border border-[rgba(248,113,113,0.35)] bg-[rgba(248,113,113,0.12)] px-2.5 py-1 text-xs font-semibold text-[#f87171]">
1 down
</div>
</div>

<div className="mt-4 space-y-2">
{rows.map((r) => {
const down = r.state === "down";
return (
<div
key={r.name}
className="grid grid-cols-[1fr_auto] items-center gap-3 rounded-lg bg-[#17202a] px-3 py-2.5"
>
<div className="min-w-0">
<div className="flex items-center gap-2">
<span style={{ color: down ? "#f87171" : "#6ee7b7" }}>●</span>
<span className="truncate font-mono text-sm">{r.name}</span>
</div>
<div className="ml-4 text-xs text-[var(--color-muted)]">{r.meta}</div>
</div>
<div
className="text-right font-mono text-xs"
style={{ color: down ? "#f87171" : "var(--color-muted)" }}
>
{down ? "connection refused" : r.latency}
</div>
</div>
);
})}
</div>

<div className="mt-4 rounded-lg border border-[rgba(248,113,113,0.25)] bg-[rgba(248,113,113,0.08)] p-3 text-xs">
<span className="font-semibold text-[#f87171]">🔴 Down alert sent</span>
<span className="text-[var(--color-muted)]"> · status.acme.io · email + Slack · 12s ago</span>
</div>

<p className="mt-4 text-xs text-[var(--color-muted)]">
HTTP · Keyword · SSL-expiry · TCP — checked on your interval, with
down &amp; recovery alerts to email, Slack, and Discord.
</p>
</div>
);
}
Loading