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
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ jobs:
run: yarn --immutable --network-timeout 100000
working-directory: website-next

- name: Install Playwright Chromium
run: yarn playwright install --with-deps chromium
working-directory: website-next

- name: Lint
run: yarn lint
working-directory: website-next
Expand Down
67 changes: 67 additions & 0 deletions .github/workflows/publish-website-next.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Publish Website (Next)

# When to trigger the workflow
on:
push:
branches:
- main
paths:
- .github/workflows/publish-website-next.yml
- website-next/**

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
show-progress: false
# Full history so doc pages get accurate last-updated dates.
fetch-depth: 0
sparse-checkout: website-next

- name: Install Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: 24
cache: "yarn"
cache-dependency-path: "website-next/yarn.lock"

- name: Cache Next.js Build Artifacts
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: |
website-next/.next/cache
key: ${{ runner.os }}-nextjs-next-${{ hashFiles('website-next/yarn.lock') }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-nextjs-next-${{ hashFiles('website-next/yarn.lock') }}-

- name: Install Packages
run: yarn --immutable --network-timeout 100000
working-directory: website-next

- name: Install Playwright Chromium
run: yarn playwright install --with-deps chromium
working-directory: website-next

- name: Build Website
run: yarn build
working-directory: website-next

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3

- name: Build Website Container
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
with:
context: ./website-next
file: ./website-next/Dockerfile
push: false
tags: ccc-website-next-${{ github.ref_name }}:${{ github.run_id }}
cache-from: type=gha,scope=website-next
cache-to: type=gha,scope=website-next,mode=max
20 changes: 20 additions & 0 deletions website-next/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
**/node_modules
**/.next
**/.turbo
**/.cache
**/.git
**/.github
**/.vscode
**/.idea
**/.DS_Store
**/storybook-static
**/.storybook
**/tsconfig.tsbuildinfo
**/*.log
**/coverage
**/test-results
Dockerfile
.dockerignore
README.md
AGENTS.md
CLAUDE.md
24 changes: 24 additions & 0 deletions website-next/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# syntax=docker/dockerfile:1
FROM nginx:alpine

# replace stock config
RUN rm -f /etc/nginx/nginx.conf /etc/nginx/conf.d/default.conf

COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
COPY ./nginx/conf.d /etc/nginx/conf.d

# pre-built Next.js static export
COPY ./out /usr/share/nginx/html

# pre-compress text assets so gzip_static can serve them
RUN find /usr/share/nginx/html -type f \
\( -name '*.html' -o -name '*.css' -o -name '*.js' -o -name '*.mjs' \
-o -name '*.json' -o -name '*.svg' -o -name '*.xml' -o -name '*.txt' \
-o -name '*.map' -o -name '*.ico' -o -name '*.webmanifest' \) \
-size +1024c \
-exec gzip -9 -k -f {} \;

EXPOSE 80

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget -q --spider http://127.0.0.1/ || exit 1
38 changes: 1 addition & 37 deletions website-next/app/(content)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,14 @@
import Link from "next/link";

const blogs: { href: string; title: string }[] = [
{
href: "/blogs/2026/05/09/linking-between-posts",
title: "Linking between blog posts (relative .md links demo)",
},
{ href: "/blogs/2025/02/01/hot-chocolate-15", title: "Hot Chocolate 15" },
{ href: "/blogs/2024/10/07/introducing-nitro", title: "Introducing Nitro" },
{ href: "/blogs/2024/08/30/hot-chocolate-14", title: "Hot Chocolate 14" },
{
href: "/blogs/2023/08/15/graphql-fusion",
title: "Announcing GraphQL Fusion",
},
{ href: "/blogs/2019/05/08/performance", title: "Performance Improvements" },
];

export default function Home() {
return (
<>
<h2>Docs</h2>
<ul>
<li>
<Link href="/docs/fusion">Fusion</Link>
</li>
<li>
<Link href="/docs/hotchocolate">Hot Chocolate</Link>
</li>
<li>
<Link href="/docs/mocha">Mocha</Link>
</li>
<li>
<Link href="/docs/nitro">Nitro</Link>
</li>
<li>
<Link href="/docs/strawberryshake">Strawberry Shake</Link>
<Link href="/docs/example/getting-started">Example</Link>
</li>
</ul>

<h2>Blog</h2>
<ul>
{blogs.map((blog) => (
<li key={blog.href}>
<Link href={blog.href}>{blog.title}</Link>
</li>
))}
</ul>
</>
);
}
17 changes: 17 additions & 0 deletions website-next/app/(content)/resources/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Typography } from "@/src/design-system/Typography";

export const metadata = {
title: "Resources",
description: "ChilliCream brand resources and downloads.",
};

export default function ResourcesPage() {
return (
<>
<Typography variant="h1">Resources</Typography>
<p className="text-stone-600">
Brand assets, banners, and other resources are coming soon.
</p>
</>
);
}
46 changes: 46 additions & 0 deletions website-next/app/blogs/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import Link from "next/link";
import { Typography } from "@/src/design-system/Typography";
import { listBlogPosts } from "@/src/helpers/blogPaths";

export const metadata = {
title: "Blog",
description: "The ChilliCream blog: announcements, deep dives, and how-tos.",
};

export default function BlogsIndex() {
const posts = listBlogPosts().filter(
({ parsed }) => parsed.slug !== "__empty__",
);

return (
<div className="px-5 py-8 sm:px-12">
<div className="mx-auto max-w-5xl">
<Typography variant="h1">Blog</Typography>
{posts.length === 0 ? (
<p className="text-stone-600">
New posts are on their way. Check back soon.
</p>
) : (
<ul className="mt-6 flex flex-col gap-3">
{posts.map(({ parsed }) => {
const href = `/blogs/${parsed.year}/${parsed.month}/${parsed.day}/${parsed.slug}`;
return (
<li key={href}>
<Link
href={href}
className="block rounded-md border border-stone-200 p-4 text-stone-800 no-underline transition-colors hover:border-fuchsia-700 hover:text-fuchsia-700"
>
<div className="font-medium">{parsed.slug}</div>
<div className="text-sm text-stone-500">
{parsed.year}-{parsed.month}-{parsed.day}
</div>
</Link>
</li>
);
})}
</ul>
)}
</div>
</div>
);
}
37 changes: 24 additions & 13 deletions website-next/app/docs/[...slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,32 @@ import fs from "node:fs";
import path from "node:path";
import type { Metadata } from "next";
import { notFound } from "next/navigation";
import { DocPageMeta } from "@/src/design-system/DocPageMeta";
import { TableOfContents } from "@/src/design-system/TableOfContents";
import { Typography } from "@/src/design-system/Typography";
import { compileDoc } from "@/src/helpers/compileDoc";
import { getGitMetadata } from "@/src/helpers/gitMetadata";
import { readFrontmatter } from "@/src/helpers/readFrontmatter";

const CONTENT_ROOT = path.join(process.cwd(), "content/docs");

type Params = {
slug: string[];
};

type PageProps = {
params: Promise<Params>;
};

export const dynamicParams = false;

export function generateStaticParams(): { slug: string[] }[] {
export function generateStaticParams(): Params[] {
const params = walk(CONTENT_ROOT)
.filter((f) => /\.mdx?$/.test(f))
.map((f) => path.relative(CONTENT_ROOT, f).replace(/\.mdx?$/, ""))
.map((rel) => rel.split(path.sep))
.map((parts) =>
parts[parts.length - 1] === "index" ? parts.slice(0, -1) : parts
parts[parts.length - 1] === "index" ? parts.slice(0, -1) : parts,
)
.filter((slug) => slug.length > 0)
.map((slug) => ({ slug }));
Expand All @@ -29,9 +39,7 @@ export function generateStaticParams(): { slug: string[] }[] {

export async function generateMetadata({
params,
}: {
params: Promise<{ slug: string[] }>;
}): Promise<Metadata> {
}: PageProps): Promise<Metadata> {
const { slug } = await params;
const rel = resolveFile(slug);
if (rel === null) {
Expand All @@ -44,21 +52,17 @@ export async function generateMetadata({
};
}

export default async function DocPage({
params,
}: {
params: Promise<{ slug: string[] }>;
}) {
export default async function DocPage({ params }: PageProps) {
const { slug } = await params;
const rel = resolveFile(slug);

if (rel === null) {
notFound();
}

const { content, frontmatter, toc } = await compileDoc(
path.join(CONTENT_ROOT, rel)
);
const absolutePath = path.join(CONTENT_ROOT, rel);
const { content, frontmatter, toc } = await compileDoc(absolutePath);
const gitMeta = await getGitMetadata(absolutePath);

return (
<div className="grid grid-cols-1 2xl:grid-cols-[1fr_20rem]">
Expand All @@ -67,7 +71,14 @@ export default async function DocPage({
{frontmatter.title ? (
<Typography variant="h1">{frontmatter.title}</Typography>
) : null}

{content}

<DocPageMeta
isoDate={gitMeta.isoDate}
displayDate={gitMeta.displayDate}
author={gitMeta.author}
/>
</article>
</main>
<TableOfContents items={toc} />
Expand Down
43 changes: 43 additions & 0 deletions website-next/app/docs/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import Link from "next/link";
import { Typography } from "@/src/design-system/Typography";

export const metadata = {
title: "Documentation",
description: "Documentation for the ChilliCream GraphQL Platform.",
};

const PRODUCTS = [
{ slug: "hotchocolate", label: "Hot Chocolate" },
{ slug: "fusion", label: "Fusion" },
{ slug: "strawberryshake", label: "Strawberry Shake" },
{ slug: "nitro", label: "Nitro" },
{ slug: "mocha", label: "Mocha" },
];

export default function DocsIndex() {
return (
<div className="px-5 py-8 sm:px-12">
<div className="mx-auto max-w-5xl">
<Typography variant="h1">Documentation</Typography>
<p className="text-stone-600">
Pick a product to get started. More content is on its way.
</p>
<ul className="mt-6 grid grid-cols-1 gap-3 sm:grid-cols-2">
{PRODUCTS.map((p) => (
<li key={p.slug}>
<Link
href={`/docs/${p.slug}`}
className="block rounded-md border border-stone-200 p-4 text-stone-800 no-underline transition-colors hover:border-fuchsia-700 hover:text-fuchsia-700"
>
<div className="font-medium">{p.label}</div>
<div className="text-sm text-stone-500">
/docs/{p.slug}
</div>
</Link>
</li>
))}
</ul>
</div>
</div>
);
}
7 changes: 7 additions & 0 deletions website-next/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
@import "tailwindcss";

@theme {
--font-sans:
var(--font-inter), ui-sans-serif, system-ui, -apple-system,
BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
"Noto Sans", sans-serif;
}

html:has(:target) {
scroll-behavior: smooth;
}
Expand Down
Loading
Loading