diff --git a/website/src/app/(v2)/(marketing)/(index)/components/MarketingButton.tsx b/website/src/app/(v2)/(marketing)/(index)/components/MarketingButton.tsx index 7895c40d92..7bc5a5c006 100644 --- a/website/src/app/(v2)/(marketing)/(index)/components/MarketingButton.tsx +++ b/website/src/app/(v2)/(marketing)/(index)/components/MarketingButton.tsx @@ -5,17 +5,20 @@ export const MarketingButton = ({ children, href, target, + rel, primary = false }: { children: React.ReactNode; href: string; target?: string; + rel?: string; primary?: boolean; }) => { return ( +
+ +
+ {/*
*/} diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/CTASection.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/CTASection.tsx index 8251115c82..f6f194deed 100644 --- a/website/src/app/(v2)/(marketing)/(index)/sections/CTASection.tsx +++ b/website/src/app/(v2)/(marketing)/(index)/sections/CTASection.tsx @@ -9,8 +9,11 @@ export function CTASection() {
- - Quickstart — 5 minutes + + Get Started Talk to an engineer diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/CodeSnippetsSection.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/CodeSnippetsSection.tsx index 7b14c3352d..8b70800fe3 100644 --- a/website/src/app/(v2)/(marketing)/(index)/sections/CodeSnippetsSection.tsx +++ b/website/src/app/(v2)/(marketing)/(index)/sections/CodeSnippetsSection.tsx @@ -4,7 +4,7 @@ export function CodeSnippetsSection() { return (
-

+

See It In Action

diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/CommunitySection.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/CommunitySection.tsx index 275357d9bd..1734c589a0 100644 --- a/website/src/app/(v2)/(marketing)/(index)/sections/CommunitySection.tsx +++ b/website/src/app/(v2)/(marketing)/(index)/sections/CommunitySection.tsx @@ -39,7 +39,7 @@ export function CommunitySection() { return (

-

+

Join the Community

diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/DeploymentOptionsSection.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/DeploymentOptionsSection.tsx index be72ca6e6f..06dbe737bc 100644 --- a/website/src/app/(v2)/(marketing)/(index)/sections/DeploymentOptionsSection.tsx +++ b/website/src/app/(v2)/(marketing)/(index)/sections/DeploymentOptionsSection.tsx @@ -1,5 +1,6 @@ import Link from "next/link"; import { CopyCommand } from "../components/CopyCommand"; +import { MarketingButton } from "../components/MarketingButton"; interface DeploymentOptionProps { title: string; @@ -10,7 +11,7 @@ interface DeploymentOptionProps { function DeploymentOption({ title, description, children }: DeploymentOptionProps) { return (

-

{title}

+

{title}

{description}

{children}
@@ -22,68 +23,75 @@ export function DeploymentOptionsSection() {
-

+

Run It Your Way

-

- Deploy Rivet however works best for your team, from local development to production at scale. -

- -
Sign In with Rivet +
+
+ + +
- View Pricing + Contact Sales
-
+
- View Self-Hosting Docs + Get the source code -
- -
-
-

Hybrid Deployment

-

- Run in Rivet Cloud for production, use self-hosting for on-premises deployments -

+
+ +
+ + Quickstart + + +
+
diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/FeaturesBentoBox.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/FeaturesBentoBox.tsx new file mode 100644 index 0000000000..ee8a9f8a01 --- /dev/null +++ b/website/src/app/(v2)/(marketing)/(index)/sections/FeaturesBentoBox.tsx @@ -0,0 +1,290 @@ +"use client"; + +import { useRef } from "react"; +import Link from "next/link"; +import { Icon } from "@rivet-gg/icons"; +import { + faDatabase, + faBolt, + faMoon, + faClock, + faShieldHalved, + faRocket, + faCheckCircle, +} from "@rivet-gg/icons"; + +interface FeatureCardProps { + title: string; + description: string; + href: string; + className?: string; + icon: any; + variant?: "default" | "large" | "medium" | "small" | "wide" | "code"; +} + +function FeatureCard({ + title, + description, + href, + className = "", + icon, + variant = "default", +}: FeatureCardProps) { + const cardRef = useRef(null); + + const handleMouseMove = (e: React.MouseEvent) => { + if (!cardRef.current) return; + const card = cardRef.current; + + const iconContainer = card.querySelector('.icon-spotlight-container') as HTMLElement; + if (!iconContainer) return; + + const iconRect = iconContainer.getBoundingClientRect(); + const x = ((e.clientX - iconRect.left) / iconRect.width) * 100; + const y = ((e.clientY - iconRect.top) / iconRect.height) * 100; + + iconContainer.style.setProperty('--mouse-x', `${x}%`); + iconContainer.style.setProperty('--mouse-y', `${y}%`); + }; + + if (variant === "large") { + return ( + +
+
+ +
+
+
+ +
+

+ {title} +

+

+ {description} +

+
+
+
+ + ); + } + + if (variant === "medium") { + return ( + +
+
+ +
+ +

+ {title} +

+

+ {description} +

+
+
+ + ); + } + + if (variant === "small") { + return ( + +
+
+ +
+
+ +
+

+ {title} +

+

+ {description} +

+
+
+ + ); + } + + if (variant === "code") { + return ( +
+
+

+ {title} +

+
+						
+							const counter = actor({`{`}{"\n"}
+							{`  `}state: {`{ `}count: 0 {`}`},{`\n`}
+							{`  `}actions: {`{`}{"\n"}
+							{`    `}increment: (c) => {`{`}{"\n"}
+							{`      `}c.state.count++;{`\n`}
+							{`      `}c.broadcast("changed", c.state.count);{`\n`}
+							{`    `}{`}`}{`\n`}
+							{`  `}{`}`}{`\n`}
+							{`});`}
+						
+					
+
+
+ ); + } + + return ( + +
+
+ +
+

+ {title} +

+

+ {description} +

+
+ +
+
+ +
+
+
+ + ); +} + +export function FeaturesBentoBox() { + const features = [ + { + title: "Long-Lived Stateful Compute", + description: "Like AWS Lambda but with persistent memory and no timeouts. Your actors remember state between requests and intelligently hibernate when idle to save resources.", + href: "/docs/actors", + icon: faBolt, + variant: "large" as const, + }, + { + title: "Blazing-Fast Performance", + description: "State stored on the same machine as compute. Ultra-fast reads/writes with no database round trips.", + href: "/docs/actors/state", + icon: faRocket, + variant: "medium" as const, + }, + { + title: "Built-in Realtime", + description: "WebSockets & SSE support out of the box. Update state and broadcast changes instantly.", + href: "/docs/actors/events", + icon: faBolt, + variant: "medium" as const, + }, + { + title: "Fault Tolerant", + description: "Built-in error handling & recovery", + href: "/docs/actors/lifecycle", + icon: faShieldHalved, + variant: "small" as const, + }, + { + title: "Auto-Hibernation", + description: "Actors sleep when idle, wake instantly on demand", + href: "/docs/actors/lifecycle", + icon: faMoon, + variant: "small" as const, + }, + { + title: "Scheduling", + description: "Persistent timeouts survive restarts and crashes", + href: "/docs/actors/schedule", + icon: faClock, + variant: "small" as const, + }, + { + title: "RPC & Events", + description: "Full-featured messaging system", + href: "/docs/actors/actions", + icon: faDatabase, + variant: "small" as const, + }, + ]; + + return ( +
+
+

+ Each lightweight Actor comes packed with features +

+
+ {/* Large hero feature */} + + + {/* Medium features */} + + + + + {/* Small features */} + {features.slice(3).map((feature) => ( + + ))} +
+
+
+ ); +} diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/FeaturesSection.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/FeaturesSection.tsx index 519a02a81b..d1498f3853 100644 --- a/website/src/app/(v2)/(marketing)/(index)/sections/FeaturesSection.tsx +++ b/website/src/app/(v2)/(marketing)/(index)/sections/FeaturesSection.tsx @@ -70,7 +70,7 @@ export function FeaturesSection() {
-

+

Built for Modern Applications

diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/HeroSection.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/HeroSection.tsx index d783e3de4c..341cb71b5b 100644 --- a/website/src/app/(v2)/(marketing)/(index)/sections/HeroSection.tsx +++ b/website/src/app/(v2)/(marketing)/(index)/sections/HeroSection.tsx @@ -14,17 +14,13 @@ export function HeroSection() {

{/* Title */}

- {/*Lightweight library for building modern backends*/} - {/*Library for building stateful applications and distributed systems*/} - {/*Build and scale stateful workloads*/} - State + Compute = Less Complexity + The Primitive for Real-Time and Agent Applications

- Rivet Actors merge state and compute in to a primitive that scales effortlessly with less complex infrastructure. - Easily self-hostable and works with your infrastructure. + Rivet Actors are a simple primitive that provides in-memory state with WebSockets, fault-tolerance, and hibernation.

{/*

@@ -95,10 +91,10 @@ export function HeroSection() { {/* CTA Buttons */}

- Quickstart — 5 minutes + Get Started diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/QuotesSection.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/QuotesSection.tsx index 7295a83d9c..21e135af3a 100644 --- a/website/src/app/(v2)/(marketing)/(index)/sections/QuotesSection.tsx +++ b/website/src/app/(v2)/(marketing)/(index)/sections/QuotesSection.tsx @@ -135,7 +135,7 @@ export function QuotesSection() { return (
-

+

What People Are Saying

diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/StudioSection.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/StudioSection.tsx index 6e3452ce37..b4b8e31fce 100644 --- a/website/src/app/(v2)/(marketing)/(index)/sections/StudioSection.tsx +++ b/website/src/app/(v2)/(marketing)/(index)/sections/StudioSection.tsx @@ -94,19 +94,17 @@ export function StudioSection() { {/* Header */}

- Built-In Observability at Scale + Built-In Observability

- Powerful debugging and monitoring tools that work - seamlessly from local development to production at - scale. + Powerful debugging and monitoring tools that work from local development to production.

{/* Visit the Studio link */}
diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/TechSection.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/TechSection.tsx index cb4f33e53e..0921afba4e 100644 --- a/website/src/app/(v2)/(marketing)/(index)/sections/TechSection.tsx +++ b/website/src/app/(v2)/(marketing)/(index)/sections/TechSection.tsx @@ -2,18 +2,14 @@ import Link from "next/link"; import Image from "next/image"; // Platform images -import rivetWhiteLogo from "../images/platforms/rivet-white.svg"; import cloudflareWorkersLogo from "../images/platforms/cloudflare-workers.svg"; import bunLogo from "../images/platforms/bun.svg"; import denoLogo from "../images/platforms/deno.svg"; import nodejsLogo from "../images/platforms/nodejs.svg"; -import fileSystemLogo from "../images/platforms/file-system.svg"; -import memoryLogo from "../images/platforms/memory.svg"; import vercelLogo from "../images/platforms/vercel.svg"; import awsLambdaLogo from "../images/platforms/aws-lambda.svg"; import awsLogo from "../images/platforms/aws-light.svg"; import supabaseLogo from "../images/platforms/supabase.svg"; -import postgresLogo from "../images/platforms/postgres.svg"; import railwayLogo from "../images/platforms/railway.svg"; import freestyleLogo from "../images/platforms/freestyle.svg"; import gcpLogo from "../images/platforms/gcp.svg"; @@ -76,7 +72,7 @@ function TechLink({ href, name, icon, alt, external, status }: TechLinkProps) { : status === "help-wanted" ? "bg-[#0059ff] text-white" : status === "1-click-deploy" - ? "bg-[#007aff] text-white" + ? "bg-[#3ECF8E] text-white" : ""; return ( @@ -101,14 +97,14 @@ function TechLink({ href, name, icon, alt, external, status }: TechLinkProps) { } interface TechSubSectionProps { - title: string; + title?: string; children: React.ReactNode; } function TechSubSection({ title, children }: TechSubSectionProps) { return (
-

{title}

+ {title &&

{title}

}
{children}
@@ -152,7 +148,7 @@ function TechSectionText({ return (
-

+

{heading}

@@ -196,35 +192,7 @@ export function TechSection() { /> - - - - - - - - + void; } function UseCaseCard({ @@ -21,6 +23,7 @@ function UseCaseCard({ className = "", iconPath, variant = "default", + onHover, }: UseCaseCardProps) { const cardRef = useRef(null); @@ -51,6 +54,8 @@ function UseCaseCard({ href={href} className={`group relative block ${className}`} onMouseMove={handleMouseMove} + onMouseEnter={() => onHover?.(title)} + onMouseLeave={() => onHover?.(null)} >
{/* Gradient overlay on hover */} @@ -105,6 +110,8 @@ function UseCaseCard({ href={href} className={`group relative block ${className}`} onMouseMove={handleMouseMove} + onMouseEnter={() => onHover?.(title)} + onMouseLeave={() => onHover?.(null)} >
{/* Gradient overlay on hover */} @@ -130,6 +137,8 @@ function UseCaseCard({ } export function UseCases() { + const [hoveredTitle, setHoveredTitle] = useState(null); + // Map the use cases we want to display const selectedUseCases = [ useCases.find((uc) => uc.title === "Agent Orchestration & MCP")!, // agent orchestration & mcp @@ -200,6 +209,25 @@ export function UseCases() { return (
+

+ Actors make it simple to build{" "} + + + {hoveredTitle && ( + + {hoveredTitle} + + )} + + +

{/* First item - takes 6 columns (half width on medium+) */} {/* Remaining items - 3 columns each (quarter width on medium+) */} @@ -220,6 +249,7 @@ export function UseCases() { href={useCase.href} iconPath={getIconPath(useCase.title)} className="md:col-span-3" + onHover={setHoveredTitle} /> ))}
diff --git a/website/src/app/(v2)/(marketing)/cloud/page.tsx b/website/src/app/(v2)/(marketing)/cloud/page.tsx deleted file mode 100644 index 6c5584a7d3..0000000000 --- a/website/src/app/(v2)/(marketing)/cloud/page.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import { ArchitectureSection } from "./ArchitectureSection"; -import { CommandCenterSection } from "./CommandCenterSection"; -import { CtaSection } from "./CtaSection"; -import { ServerlessLimitationsSection } from "./ServerlessLimitationsSection"; -import { Icon, faArrowRight } from "@rivet-gg/icons"; -import { MarketingButton } from "./MarketingButton"; -import Link from "next/link"; - -export default function IndexPage() { - // an empty div at the top of the page is a workaround for a bug in Next.js that causes the page to jump when the user navigates to it - // https://github.com/vercel/next.js/discussions/64534 - return ( - <> -
- - {/* BG gradient */} - {/*
*/} - - {/* Content */} -
- - - - {/**/} - {/**/} - - -
- - ); -} -// Hero component with title, subtitle, and CTA buttons -const Hero = () => { - return ( -
-
- {" "} - {/* Width/padding ocpied from FancyHeader */} -
- {/* On-Prem CF Workers */} - {/*
- -
- - Need on-prem{" "} - - Cloudflare Workers - {" "} - or{" "} - - Durable Objects - - ? - - -
- -
- -
*/} - - {/* Title */} -
-

- Scale and manage your Actors on Rivet Cloud -

-

- Rivet cloud scales actors that connect seamlessly to your applications deployed anywhere -

-
- -
- - {/* CTA */} -
-
- - Get Started - - - Documentation - - -
-
- - {/*
-

or run locally with Docker

- -
*/} -
-
-
- ); -}; diff --git a/website/src/components/v2/Header.tsx b/website/src/components/v2/Header.tsx index e78df4ffec..9d21b8b31a 100644 --- a/website/src/components/v2/Header.tsx +++ b/website/src/components/v2/Header.tsx @@ -263,11 +263,13 @@ function DocsMobileNavigation({ tree }) { if (pathname.startsWith("/docs/actors")) return "actors"; if (pathname.startsWith("/docs/integrations")) return "integrations"; if (pathname.startsWith("/docs/api")) return "api"; + if (pathname.startsWith("/docs/quickstart")) return "quickstart"; return "overview"; }; const sections = [ { id: "overview", label: "Overview", href: "/docs" }, + { id: "quickstart", label: "Quickstart", href: "/docs/quickstart" }, { id: "actors", label: "Actors", href: "/docs/actors" }, { id: "integrations", label: "Integrations", href: "/docs/integrations" }, { id: "api", label: "API Reference", href: "/docs/api" }, diff --git a/website/src/content/docs/quickstart/index.mdx b/website/src/content/docs/quickstart/index.mdx new file mode 100644 index 0000000000..2ab45d7911 --- /dev/null +++ b/website/src/content/docs/quickstart/index.mdx @@ -0,0 +1,21 @@ +import { faNodeJs, faReact, faNextjs, faCloudflare } from "@rivet-gg/icons"; + +# Quickstart + +Get started with Rivet in minutes. Choose your preferred framework or runtime to begin building with actors. + + + + Set up actors with Node.js, Bun, and web frameworks + + + Build real-time React applications with actors + + + Build server-rendered Next.js experiences backed by actors + + + Deploy actors on Cloudflare Workers with zero infrastructure + + + diff --git a/website/src/sitemap/mod.ts b/website/src/sitemap/mod.ts index dc1158978a..15725770c4 100644 --- a/website/src/sitemap/mod.ts +++ b/website/src/sitemap/mod.ts @@ -108,34 +108,6 @@ export const sitemap = [ href: "/docs", icon: faSquareInfo, }, - { - title: "Quickstart", - icon: faForward, - collapsible: true, - href: "/docs/actors/quickstart", - pages: [ - { - title: "Node.js & Bun", - href: "/docs/actors/quickstart/backend", - icon: faNodeJs, - }, - { - title: "React", - href: "/docs/actors/quickstart/react", - icon: faReact, - }, - { - title: "Next.js", - href: "/docs/actors/quickstart/next-js", - icon: faNextjs, - }, - { - title: "Cloudflare Workers", - href: "/docs/actors/quickstart/cloudflare-workers", - icon: faCloudflare, - }, - ], - }, ] }, { @@ -358,6 +330,47 @@ export const sitemap = [ }, ], }, + { + title: "Quickstart", + href: "/docs/quickstart", + sidebar: [ + { + title: "General", + pages: [ + { + title: "Overview", + href: "/docs/quickstart", + icon: faForward, + }, + ], + }, + { + title: "Guides", + pages: [ + { + title: "Node.js & Bun", + href: "/docs/actors/quickstart/backend", + icon: faNodeJs, + }, + { + title: "React", + href: "/docs/actors/quickstart/react", + icon: faReact, + }, + { + title: "Next.js", + href: "/docs/actors/quickstart/next-js", + icon: faNextjs, + }, + { + title: "Cloudflare Workers", + href: "/docs/actors/quickstart/cloudflare-workers", + icon: faCloudflare, + }, + ], + }, + ], + }, { title: "Integrations", href: "/docs/integrations",