Files
zeekay 712a10d0f3 Lead the blog with Zen 6 and its two jobs
The home now says who makes Zen LM, Zoo Labs Foundation, a 501(c)(3)
non-profit, the two jobs it is chosen for, that Zen 6 and Zen 6 Flash
are available now, and that Zen 7 is a research preview with a link
to request access. The footer names the foundation, and "Qwen" leaves
the site keywords.

Posts marked "upstream: true" carry data-upstream on their page, card
and read-more link, and scripts/check-zen.mjs fails the build when a
name from zen.upstream shows anywhere else.

The build stops measuring remote images: fumadocs fetched every one to
read its size, and a single host answering 403 failed the build.
2026-09-30 07:01:46 -07:00

168 lines
5.9 KiB
TypeScript

import { docs, meta } from "@/.source";
import { DocsBody } from "fumadocs-ui/page";
import { loader } from "fumadocs-core/source";
import { createMDXSource } from "fumadocs-mdx";
import { notFound } from "next/navigation";
import { ArrowLeft } from "lucide-react";
import { Button } from "@/components/ui/button";
import Link from "next/link";
import Image from "next/image";
import { TableOfContents } from "@/components/table-of-contents";
import { MobileTableOfContents } from "@/components/mobile-toc";
import { AuthorCard } from "@/components/author-card";
import { ReadMoreSection } from "@/components/read-more-section";
import { getAuthor, isValidAuthor } from "@/lib/authors";
import { FlickeringGrid } from "@/components/magicui/flickering-grid";
import { HashScrollHandler } from "@/components/hash-scroll-handler";
export { generateMetadata } from "./metadata";
interface PageProps {
params: Promise<{ slug: string }>;
}
const blogSource = loader({
baseUrl: "/blog",
source: createMDXSource(docs, meta),
});
export function generateStaticParams() {
return blogSource.getPages().map((page) => ({
slug: page.slugs[0],
}));
}
const formatDate = (date: Date): string => {
return date.toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "numeric",
});
};
export default async function BlogPost({ params }: PageProps) {
const { slug } = await params;
if (!slug || slug.length === 0) {
notFound();
}
const page = blogSource.getPage([slug]);
if (!page) {
notFound();
}
const MDX = page.data.body;
const date = page.data.date ? new Date(page.data.date as string) : new Date();
const formattedDate = formatDate(date);
return (
<div
className="min-h-screen bg-background relative"
data-upstream={page.data.upstream ? "" : undefined}
>
<HashScrollHandler />
<div className="absolute top-0 left-0 z-0 w-full h-[200px] [mask-image:linear-gradient(to_top,transparent_25%,black_95%)]">
<FlickeringGrid
className="absolute top-0 left-0 size-full"
squareSize={4}
gridGap={6}
color="#6B7280"
maxOpacity={0.2}
flickerChance={0.05}
/>
</div>
<div className="space-y-4 border-b border-border relative z-10">
<div className="max-w-7xl mx-auto flex flex-col gap-6 p-6">
<div className="flex flex-wrap items-center gap-3 gap-y-5 text-sm text-muted-foreground">
<Button variant="outline" asChild className="h-6 w-6">
<Link href="/">
<ArrowLeft className="w-4 h-4" />
<span className="sr-only">Back to all articles</span>
</Link>
</Button>
{Array.isArray(page.data.tags) && page.data.tags.length > 0 ? (
<div className="flex flex-wrap gap-3 text-muted-foreground">
{page.data.tags.map((tag: string) => (
<span
key={tag}
className="h-6 w-fit px-3 text-sm font-medium bg-muted text-muted-foreground rounded-md border flex items-center justify-center"
>
{tag}
</span>
))}
</div>
) : null}
<time className="font-medium text-muted-foreground">
{formattedDate}
</time>
</div>
<h1 className="text-4xl md:text-5xl lg:text-6xl font-medium tracking-tighter text-balance">
{page.data.title}
</h1>
{page.data.description && (
<p className="text-muted-foreground max-w-4xl md:text-lg md:text-balance">
{page.data.description}
</p>
)}
</div>
</div>
<div className="flex divide-x divide-border relative max-w-7xl mx-auto px-4 md:px-0 z-10">
<div className="absolute max-w-7xl mx-auto left-1/2 -translate-x-1/2 w-[calc(100%-2rem)] lg:w-full h-full border-x border-border p-0 pointer-events-none" />
<main className="w-full p-0 overflow-hidden">
{page.data.thumbnail ? (
<div className="relative w-full h-[500px] overflow-hidden object-cover border border-transparent">
<Image
src={page.data.thumbnail as string}
alt={page.data.title}
fill
className="object-cover"
priority
/>
</div>
) : null}
<div className="p-6 lg:p-10">
<div className="prose dark:prose-invert max-w-none prose-headings:scroll-mt-8 prose-headings:font-semibold prose-a:no-underline prose-headings:tracking-tight prose-headings:text-balance prose-p:tracking-tight prose-p:text-balance prose-lg">
<DocsBody>
<MDX />
</DocsBody>
</div>
</div>
<div className="mt-10">
<ReadMoreSection
currentSlug={[slug]}
currentTags={Array.isArray(page.data.tags) ? page.data.tags : undefined}
/>
</div>
</main>
<aside className="hidden lg:block w-[350px] flex-shrink-0 p-6 lg:p-10 bg-muted/60 dark:bg-muted/20">
<div className="sticky top-20 space-y-8">
{page.data.author && typeof page.data.author === 'string' && isValidAuthor(page.data.author) ? (
<AuthorCard author={getAuthor(page.data.author)} />
) : page.data.author ? (
<div className="flex items-start gap-2">
<div className="flex-1">
<h3 className="text-sm tracking-tight text-balance font-semibold">
{page.data.author as string}
</h3>
</div>
</div>
) : null}
<div className="border border-border rounded-lg p-6 bg-card">
<TableOfContents />
</div>
</div>
</aside>
</div>
<MobileTableOfContents />
</div>
);
}