Skip to content
Closed
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
1 change: 1 addition & 0 deletions apps/website/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.vercel
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const CenteredSection = ({
children,
}: CenteredSectionProps) => (
<div className="grid items-center gap-10 overflow-hidden px-4 py-8 sm:px-12 sm:py-12">
<div className="mx-auto grid max-w-2xl gap-4 text-center">
<div className="mx-auto grid max-w-lg gap-4 text-center">
<h2 className="font-semibold text-xl tracking-tight sm:text-2xl md:text-3xl lg:text-[40px]">
{title}
</h2>
Expand Down
12 changes: 5 additions & 7 deletions apps/website/app/[lang]/(home)/components/hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { ReactNode } from "react";
import { Badge } from "@/components/ui/badge";

interface HeroProps {
badge?: string;
badge: string;
children: ReactNode;
description: string;
title: string;
Expand All @@ -11,12 +11,10 @@ interface HeroProps {
export const Hero = ({ badge, title, description, children }: HeroProps) => (
<section className="mt-(--fd-nav-height) space-y-6 px-4 pt-16 pb-16 text-center sm:pt-24">
<div className="mx-auto w-full max-w-4xl space-y-5">
{badge ? (
<Badge className="rounded-full" variant="secondary">
<div className="size-2 rounded-full bg-muted-foreground" />
<p>{badge}</p>
</Badge>
) : null}
<Badge className="rounded-full" variant="secondary">
<div className="size-2 rounded-full bg-muted-foreground" />
<p>{badge}</p>
</Badge>
<h1 className="text-balance text-center font-semibold text-[40px]! leading-[1.1] tracking-tight sm:text-5xl! lg:font-semibold xl:text-6xl!">
{title}
</h1>
Expand Down
4 changes: 2 additions & 2 deletions apps/website/app/[lang]/(home)/components/templates.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import Image, { type StaticImageData } from "next/image";
import Image from "next/image";
import { cn } from "@/lib/utils";

interface TemplatesProps {
data: {
title: string;
description: string;
link: string;
image: string | StaticImageData;
image: string;
}[];
description: string;
title: string;
Expand Down
10 changes: 3 additions & 7 deletions apps/website/app/[lang]/(home)/components/text-grid-section.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
import type { ReactNode } from "react";

interface TextGridSectionProps {
data: {
id: string;
title: string;
description: ReactNode;
description: string;
}[];
}

export const TextGridSection = ({ data }: TextGridSectionProps) => (
<div className="grid gap-8 px-4 py-8 sm:grid-cols-2 sm:px-12 sm:py-12 md:grid-cols-3">
<div className="grid gap-8 px-4 py-8 sm:px-12 sm:py-12 md:grid-cols-3">
{data.map((item) => (
<div key={item.id}>
<h3 className="mb-2 font-semibold text-lg tracking-tight">
{item.title}
</h3>
<p className="text-muted-foreground [&_a]:font-medium [&_a]:text-primary [&_a]:underline">
{item.description}
</p>
<p className="text-muted-foreground">{item.description}</p>
</div>
))}
</div>
Expand Down
158 changes: 42 additions & 116 deletions apps/website/app/[lang]/(home)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,14 @@ import { Installer } from "@/components/geistdocs/installer";
import { Button } from "@/components/ui/button";
import { CenteredSection } from "./components/centered-section";
import { CTA } from "./components/cta";
import { Demo } from "./components/demo";
import { Hero } from "./components/hero";
import { Logos } from "./components/logos";
import { OneTwoSection } from "./components/one-two-section";
import { Templates } from "./components/templates";
import { TextGridSection } from "./components/text-grid-section";
import { Usage } from "./components/usage";
import AiElements from "./images/ai-elements.png";
import NextjsChatbotTemplate from "./images/nextjs-chatbot-template.png";
import VibeCodingPlatform from "./images/vibe-coding-platform.png";

const title = "Streamdown";
const title = "Geistdocs";
const description =
"A markdown renderer designed for streaming content from AI models. Highly interactive, customizable, and easy to use.";
"A Vercel documentation template built with Next.js and Fumadocs. Designed for spinning up documentation sites quickly and consistently.";

export const metadata: Metadata = {
title,
Expand All @@ -26,147 +20,79 @@ export const metadata: Metadata = {

const templates = [
{
title: "Next.js Chatbot Template",
description:
"A free, open-source template that helps you dive right into building powerful chatbot applications.",
link: "https://github.com/vercel/ai-chatbot",
image: NextjsChatbotTemplate,
title: "Template 1",
description: "Description of template 1",
link: "https://example.com/template-1",
image: "https://placehold.co/600x400.png",
},
{
title: "AI Elements",
description:
"A collection of UI elements for building AI-powered applications.",
link: "https://elements.ai-sdk.dev/",
image: AiElements,
title: "Template 2",
description: "Description of template 2",
link: "https://example.com/template-2",
image: "https://placehold.co/600x400.png",
},
{
title: "Vibe Coding Platform",
description: "An end to end text-to-app coding platform.",
link: "https://oss-vibe-coding-platform.vercel.app/",
image: VibeCodingPlatform,
title: "Template 3",
description: "Description of template 3",
link: "https://example.com/template-3",
image: "https://placehold.co/600x400.png",
},
];

const Link = DynamicLink;

const features = [
{
id: "typography",
title: "Typography & GFM",
description: (
<>
Built-in <Link href="/[lang]/docs/typography">Tailwind typography</Link>{" "}
for headings, lists, and code blocks.{" "}
<Link href="/[lang]/docs/gfm">GitHub Flavored Markdown</Link> adds
tables, task lists, strikethrough, and autolinks.
</>
),
},
{
id: "streaming",
title: "Streaming experience",
description: (
<>
Built-in <Link href="/[lang]/docs/carets">caret indicators</Link> show
users content is generating.{" "}
<Link href="/[lang]/docs/termination">Unterminated block styling</Link>{" "}
parses incomplete Markdown for prettier streaming with smooth{" "}
<Link href="/[lang]/docs/animation">animations</Link>.
</>
),
},
{
id: "code",
title: "Interactive code blocks",
description: (
<>
<Link href="/[lang]/docs/plugins/code">Shiki-powered</Link> syntax
highlighting with{" "}
<Link href="/[lang]/docs/interactivity">copy and download buttons</Link>
. Supports language detection and line numbers.
</>
),
},
const textGridSection = [
{
id: "plugins",
title: "Math, diagrams & CJK",
description: (
<>
<Link href="/[lang]/docs/plugins/math">LaTeX math</Link> through KaTeX,
interactive{" "}
<Link href="/[lang]/docs/plugins/mermaid">Mermaid diagrams</Link> with
fullscreen viewing, and{" "}
<Link href="/[lang]/docs/plugins/cjk">CJK support</Link> for correct
ideographic punctuation.
</>
),
id: "1",
title: "Text Grid Section",
description: "Description of text grid section",
},
{
id: "security",
title: "Security & link safety",
description: (
<>
<Link href="/[lang]/docs/security">Security hardening</Link> blocks
images and links from unexpected origins.{" "}
<Link href="/[lang]/docs/link-safety">Link safety modals</Link> display
the full URL before navigation to protect users.
</>
),
id: "2",
title: "Text Grid Section",
description: "Description of text grid section",
},
{
id: "customization",
title: "Fully customizable",
description: (
<>
Override any element with{" "}
<Link href="/[lang]/docs/components">custom components</Link>, apply
your own <Link href="/[lang]/docs/styling">styles</Link>, and fine-tune
behavior through{" "}
<Link href="/[lang]/docs/configuration">configuration</Link>.
Tree-shakeable <Link href="/[lang]/docs/plugins">plugins</Link> keep
your bundle lean.
</>
),
id: "3",
title: "Text Grid Section",
description: "Description of text grid section",
},
];

const HomePage = () => (
<div className="container mx-auto max-w-5xl">
<Hero description={description} title={title}>
<Hero
badge="Geistdocs is now in beta"
description={description}
title={title}
>
<div className="mx-auto inline-flex w-fit items-center gap-3">
<Installer command="npm i streamdown" />
<Button asChild className="px-4" size="lg" variant="outline">
<Button asChild className="px-4" size="lg">
<DynamicLink href="/[lang]/docs/getting-started">
Read the docs
Get Started
</DynamicLink>
</Button>
<Installer command="npx @vercel/geistdocs init" />
</div>
</Hero>
<div className="grid divide-y border-y sm:border-x">
<TextGridSection data={textGridSection} />
<CenteredSection
description="Built-in typography, streaming carets, animations, plugins, and more."
title="A fully-loaded Markdown renderer"
description="Description of centered section"
title="Centered Section"
>
<Demo />
<div className="aspect-video rounded-lg border bg-background" />
</CenteredSection>
<Logos />
<TextGridSection data={features} />
<OneTwoSection
description="Install only what you need. Plugins are optional and tree-shakeable for minimal bundle size."
title="Get started in seconds"
description="Description of one/two section"
title="One/Two Section"
>
<Usage />
<div className="aspect-video rounded-lg border bg-background" />
</OneTwoSection>
<Templates
data={templates}
description="See Streamdown in action with one of our templates."
title="Showcase"
/>
<CTA
cta="Read the docs"
href="/docs"
title="Upgrade your AI experiences"
description="See Geistdocs in action with one of our templates."
title="Get started quickly"
/>
<CTA cta="Get started" href="/docs" title="Start your docs today" />
</div>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion apps/website/app/[lang]/docs/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const generateMetadata = async ({
},
alternates: {
types: {
"text/markdown": slug ? `/docs/${slug.join("/")}.md` : "/docs.md",
"text/markdown": slug ? `/docs/${slug}.md` : "/docs.md",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"text/markdown": slug ? `/docs/${slug}.md` : "/docs.md",
"text/markdown": slug ? `/docs/${slug.join("/")}.md` : "/docs.md",

Using slug array directly in template literal produces comma-separated URL segments instead of slash-separated path for nested doc pages' alternates metadata.

Fix on Vercel

},
},
};
Expand Down
2 changes: 0 additions & 2 deletions apps/website/app/[lang]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import "../global.css";
import "katex/dist/katex.css";
import "streamdown/styles.css";
import { Footer } from "@/components/geistdocs/footer";
import { Navbar } from "@/components/geistdocs/navbar";
import { GeistdocsProvider } from "@/components/geistdocs/provider";
Expand Down
2 changes: 1 addition & 1 deletion apps/website/app/[lang]/rss.xml/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const GET = async (
title: page.data.title,
description: page.data.description,
link: `${baseUrl}${page.url}`,
date: new Date(),
date: new Date(page.data.lastModified ?? new Date()),
author: [
{
name: "Vercel",
Expand Down
Loading
Loading