Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
8 changes: 8 additions & 0 deletions website-next/app/(content)/help/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import type { Metadata } from "next";

import { type Plan, PlanGrid } from "@/src/components/PlanGrid";
import { Section } from "@/src/components/Section";

export const metadata: Metadata = {
title: "Help",
description:
"Need urgent GraphQL help? Join the ChilliCream community Slack, book a session with an expert, or choose a support plan that fits your team.",
};

const PLANS: Plan[] = [
{
title: "Community",
Expand Down
8 changes: 8 additions & 0 deletions website-next/app/(content)/platform/analytics/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import type { Metadata } from "next";

import { Picture } from "@/src/design-system/Picture";

import { ContentSection } from "@/src/components/ContentSection";
import { NextStepsSection } from "@/src/components/NextStepsSection";
import { PageHero } from "@/src/components/PageHero";
import { SolidButton } from "@/src/design-system/Button";

export const metadata: Metadata = {
title: "Analytics",
description:
"Monitor your GraphQL APIs with ChilliCream analytics: real-time insights, throughput and latency metrics, and full OpenTelemetry trace exploration.",
};

export default function AnalyticsPage() {
return (
<>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import type { Metadata } from "next";

import { ContentSection } from "@/src/components/ContentSection";
import { NextStepsSection } from "@/src/components/NextStepsSection";
import { PageHero } from "@/src/components/PageHero";
import { SolidButton } from "@/src/design-system/Button";

export const metadata: Metadata = {
title: "Continuous Integration",
description:
"Ship GraphQL changes safely with ChilliCream: schema validation, a centralized registry, environment workflows, and CI/CD integration via the Nitro CLI.",
};

export default function ContinuousIntegrationPage() {
return (
<>
Expand Down
8 changes: 8 additions & 0 deletions website-next/app/(content)/platform/ecosystem/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import type { Metadata } from "next";

import { ContentSection } from "@/src/components/ContentSection";
import { NextStepsSection } from "@/src/components/NextStepsSection";
import { PageHero } from "@/src/components/PageHero";
import { Section } from "@/src/components/Section";

export const metadata: Metadata = {
title: "Ecosystem",
description:
"Explore the ChilliCream ecosystem: GraphQL tooling with authentication flows, document sync, subscriptions, and a fast IDE built for your API journey.",
};

interface FeatureCard {
title: string;
description: string;
Expand Down
7 changes: 7 additions & 0 deletions website-next/app/(content)/platform/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import type { Metadata } from "next";
import Link from "next/link";

import { PageHero } from "@/src/components/PageHero";
import { Section } from "@/src/components/Section";

export const metadata: Metadata = {
title: "Platform",
description:
"Discover the ChilliCream GraphQL Platform: one place for analytics, continuous integration, and a trusted ecosystem for every API in your organization.",
};

const PLATFORM_SECTIONS = [
{
href: "/platform/analytics",
Expand Down
8 changes: 8 additions & 0 deletions website-next/app/(content)/pricing/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import type { Metadata } from "next";

import { Typography } from "@/src/design-system/Typography";

export const metadata: Metadata = {
title: "Pricing",
description:
"Explore pricing for the ChilliCream GraphQL Platform. Compare plans and find the right option for your team, from open source to enterprise.",
};

export default function Page() {
return <Typography variant="body">TODO: Pricing page</Typography>;
}
8 changes: 8 additions & 0 deletions website-next/app/(content)/products/hotchocolate/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import type { Metadata } from "next";

import { ContentSection } from "@/src/components/ContentSection";
import { PageHero } from "@/src/components/PageHero";
import { Section } from "@/src/components/Section";
import { OutlineButton, SolidButton } from "@/src/design-system/Button";

export const metadata: Metadata = {
title: "Hot Chocolate",
description:
"Hot Chocolate is the GraphQL server for .NET: build type-safe APIs with DataLoader batching, subscriptions, OpenTelemetry, and federation via Fusion.",
};

const FEATURES = [
{
title: "Compile-time Composition",
Expand Down
8 changes: 8 additions & 0 deletions website-next/app/(content)/products/nitro/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import type { Metadata } from "next";

import { ContentSection } from "@/src/components/ContentSection";
import { PageHero } from "@/src/components/PageHero";
import { Section } from "@/src/components/Section";
import { OutlineButton, SolidButton } from "@/src/design-system/Button";

export const metadata: Metadata = {
title: "Nitro",
description:
"Nitro is ChilliCream's GraphQL IDE: explore any GraphQL API with authentication flows, document sync, and subscriptions over SSE and WebSockets.",
};

const FEATURES: { title: string; description: string }[] = [
{
title: "Authentication Flows",
Expand Down
8 changes: 8 additions & 0 deletions website-next/app/(content)/products/strawberryshake/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import type { Metadata } from "next";

import { ContentSection } from "@/src/components/ContentSection";
import { PageHero } from "@/src/components/PageHero";
import { Section } from "@/src/components/Section";
import { OutlineButton, SolidButton } from "@/src/design-system/Button";

export const metadata: Metadata = {
title: "Strawberry Shake",
description:
"Strawberry Shake is a strongly-typed GraphQL client for .NET with a reactive store, caching, subscriptions, and compile-time source generators.",
};

const FEATURES = [
{
title: "Strongly-typed Client",
Expand Down
8 changes: 8 additions & 0 deletions website-next/app/(content)/services/advisory/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import type { Metadata } from "next";

import { Offering } from "@/src/components/Offering";
import { PageHero } from "@/src/components/PageHero";

export const metadata: Metadata = {
title: "Advisory",
description:
"Get quick access to ChilliCream's GraphQL experts: hourly consulting, architecture guidance, code reviews, and full contracting engagements.",
};

interface InquiryPlan {
title: string;
description: string;
Expand Down
7 changes: 7 additions & 0 deletions website-next/app/(content)/services/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import type { Metadata } from "next";
import Link from "next/link";

import { PageHero } from "@/src/components/PageHero";
import { Section } from "@/src/components/Section";

export const metadata: Metadata = {
title: "Services",
description:
"Work with ChilliCream's GraphQL experts: advisory and consulting, support plans with SLAs you can rely on, and focused training for your team.",
};

const SERVICE_SECTIONS = [
{
href: "/services/advisory",
Expand Down
8 changes: 8 additions & 0 deletions website-next/app/(content)/services/support/contact/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import type { Metadata } from "next";

import { PageHero } from "@/src/components/PageHero";
import { ContactForm } from "./ContactForm";

export const metadata: Metadata = {
title: "Contact Us",
description:
"Contact the ChilliCream team: tell us what you need, from support plans and demos to GraphQL consulting and training, and we will be in touch shortly.",
};

export default function ContactPage() {
return (
<>
Expand Down
8 changes: 8 additions & 0 deletions website-next/app/(content)/services/support/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { Metadata } from "next";

import { type Plan, PlanGrid } from "@/src/components/PlanGrid";
import { PageHero } from "@/src/components/PageHero";
import { Section } from "@/src/components/Section";
Expand All @@ -11,6 +13,12 @@ import {
} from "@/src/design-system/Table";
import { CheckIcon } from "@/src/components/CheckIcon";

export const metadata: Metadata = {
title: "Support",
description:
"Get GraphQL support from ChilliCream experts: plans from a free community Slack to enterprise SLAs with dedicated account managers and phone support.",
};

const SUPPORT_PLANS: Plan[] = [
{
title: "Community",
Expand Down
8 changes: 8 additions & 0 deletions website-next/app/(content)/services/training/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import type { Metadata } from "next";

import { Offering } from "@/src/components/Offering";
import { PageHero } from "@/src/components/PageHero";
import { Section } from "@/src/components/Section";

export const metadata: Metadata = {
title: "Training",
description:
"Train your team with ChilliCream: corporate GraphQL training and workshops covering Hot Chocolate, ASP.NET Core, React, and Relay, taught by experts.",
};

interface CorporateService {
kind: string;
description: string;
Expand Down
Binary file added website-next/app/apple-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 43 additions & 0 deletions website-next/app/blog/[...slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,25 @@ export async function generateMetadata({
return {
title,
description,
...(summary?.author
? { authors: [{ name: summary.author, url: summary.authorUrl ?? undefined }] }
: {}),
alternates: {
canonical: summary?.href,
},
openGraph: {
type: "article",
title,
description,
images,
url: summary?.href,
publishedTime: summary?.date,
authors: summary?.authorUrl
? [summary.authorUrl]
: summary?.author
? [summary.author]
: undefined,
tags: summary && summary.tags.length > 0 ? summary.tags : undefined,
},
twitter: {
card: "summary_large_image",
Expand Down Expand Up @@ -143,8 +157,37 @@ export default async function BlogSlugPage({ params }: PageProps) {
const similar = current ? findSimilarPosts(current, summaries) : [];
const featuredImage = current?.featuredImage ?? null;

const jsonLd = current
? {
"@context": "https://schema.org",
"@type": "BlogPosting",
headline: current.title,
...(current.description ? { description: current.description } : {}),
datePublished: current.date,
...(current.featuredImage
? { image: toAbsoluteUrl(current.featuredImage) }
: {}),
...(current.author
? {
author: {
"@type": "Person",
name: current.author,
...(current.authorUrl ? { url: current.authorUrl } : {}),
},
}
: {}),
mainEntityOfPage: toAbsoluteUrl(current.href),
}
: null;

return (
<main className="px-5 py-8 sm:px-12">
{jsonLd ? (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
Comment thread
tobias-tengler marked this conversation as resolved.
Resolved
) : null}
<article className="mx-auto max-w-5xl">
{featuredImage ? (
<Picture
Expand Down
64 changes: 61 additions & 3 deletions website-next/app/docs/[...slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { EditOnGitHub } from "@/src/components/EditOnGitHub";
import { TableOfContents } from "@/src/components/TableOfContents";
import { Typography } from "@/src/design-system/Typography";
import { NotFoundContent } from "@/src/components/NotFoundContent";
import { docBreadcrumbs } from "@/src/helpers/buildContentTree";
import { compileDoc } from "@/src/helpers/compileDoc";
import {
CONTENT_ROOT,
Expand Down Expand Up @@ -71,6 +72,16 @@ export async function generateMetadata({
return {};
}
const { title, description } = readFrontmatter(path.join(CONTENT_ROOT, rel));
const gitMeta = await getGitMetadata(path.join(CONTENT_ROOT, rel));

// Surface the product in the title tag ("OpenAPI Adapter - Hot Chocolate"),
// since searches almost always include the product name. Skip the suffix on
// product index pages, where the title already is the product name.
const product = docBreadcrumbs(slug.slice(0, 1))[0]?.name;
const pageTitle =
title && product && title !== product ? `${title} - ${product}` : title;

const canonical = `/docs/${slug.join("/")}`;

const id = encodeDocId(slug);
const ogImage = {
Expand All @@ -82,17 +93,22 @@ export async function generateMetadata({
};

return {
title,
title: pageTitle,
description,
alternates: {
canonical,
},
openGraph: {
type: "article",
title,
title: pageTitle,
description,
images: [ogImage],
url: canonical,
modifiedTime: gitMeta.isoDate,
},
twitter: {
card: "summary_large_image",
title,
title: pageTitle,
description,
images: [ogImage],
},
Expand All @@ -117,9 +133,51 @@ export default async function DocPage({ params }: PageProps) {
const { content, frontmatter, toc } = await compileDoc(absolutePath);
const gitMeta = await getGitMetadata(absolutePath);

const pageHref = `/docs/${slug.join("/")}`;
const crumbs = [
{ name: "Docs", href: "/docs" },
...docBreadcrumbs(slug),
].filter((c, i, all) => c.href !== null || i === all.length - 1);
// Pages that exist on disk but are not (yet) referenced in the navigation
// tree still get a leaf crumb, named by their frontmatter title.
if (crumbs[crumbs.length - 1]?.href !== pageHref) {
crumbs.push({
name: frontmatter.title ?? slug[slug.length - 1],
href: pageHref,
});
}
const jsonLd = [
{
"@context": "https://schema.org",
"@type": "TechArticle",
headline: frontmatter.title,
...(frontmatter.description
? { description: frontmatter.description }
: {}),
dateModified: gitMeta.isoDate,
mainEntityOfPage: toAbsoluteUrl(`/docs/${slug.join("/")}`),
},
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
itemListElement: crumbs.map((c, i) => ({
"@type": "ListItem",
position: i + 1,
name: c.name,
...(c.href && i < crumbs.length - 1
? { item: toAbsoluteUrl(c.href) }
: {}),
})),
},
];

return (
<div className="grid grid-cols-1 2xl:grid-cols-[1fr_20rem]">
<main className="min-w-0 px-5 py-8 sm:px-12">
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
Comment thread
tobias-tengler marked this conversation as resolved.
Resolved
<article className="mx-auto max-w-5xl">
{frontmatter.title ? (
<Typography variant="h1">{frontmatter.title}</Typography>
Expand Down
Binary file added website-next/app/favicon.ico
Binary file not shown.
Loading
Loading