Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 7 additions & 0 deletions website-next/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,10 @@

This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
<!-- END:nextjs-agent-rules -->

# Writing documentation

When creating or editing docs under `content/docs/`, follow the conventions in
[README.md → Writing Documentation](./README.md#writing-documentation). It covers
frontmatter, `structure.yaml` sidebars, links, images, YouTube videos,
admonitions, Mermaid diagrams, and MDX gotchas.
168 changes: 168 additions & 0 deletions website-next/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# website-next

The ChilliCream website and documentation, built on Next.js (MDX-based docs).

> [!NOTE]
> This is **not** the Next.js you may know from training data. APIs, conventions,
> and file structure may differ. Read the relevant guide in
> `node_modules/next/dist/docs/` before writing app/build code.

## Development

Use `yarn` (not `npm`):

```bash
yarn
yarn dev
```

## Writing Documentation

Docs live in `content/docs/<product>/...` as Markdown (`.md`) files and are
compiled with a custom MDX pipeline (`src/mdx-plugins.ts`). The rules below are
specific to this repo. Following them keeps the build green (several of these are
enforced at build time and will fail the build if violated).

### File layout

```
content/docs/<product>/<section>/<page>.md
content/docs/<product>/<section>/structure.yaml # sidebar for that directory
content/docs/<product>/index.md # the product/section landing page
```

A directory's `index.md` is its landing page. Images do **not** live next to docs
(see [Images](#images)).

### Frontmatter

Every doc starts with YAML frontmatter:

```markdown
---
title: "Page Title"
description: "One-sentence summary used for SEO and Open Graph."
---
```

- `title` is rendered by the page layout as the page's single `<h1>`.
- **Do not repeat the title as the first heading in the body.** The layout already
shows it, so a `# Page Title` at the top produces a duplicate heading.
- Headings are **automatically demoted one level** at build time
(`src/remark/demoteHeadings.mjs`): write `#` in source and it renders as `<h2>`,
`##` renders as `<h3>`, and so on. So author your top-level sections with `#`.

### Sidebar (`structure.yaml`)

The sidebar is built by walking the directory tree
(`src/helpers/buildContentTree.ts`). **Every directory that appears in the
navigation must contain a `structure.yaml`.**

```yaml
title: Section Title
items:
- path: index # resolves to ./index.md, used as the section landing page
title: Overview
- path: getting-started # resolves to ./getting-started.md
title: Getting Started
- path: guides # a subdirectory -> must have its own structure.yaml
title: Guides
```

- `items` is a **flat** list for the current directory only. Nesting is expressed
through subdirectories, each with its own `structure.yaml`.
- A `path` resolves to `<path>.md` if that file exists, otherwise to the
subdirectory `<path>/` (which must contain `index.md` to be linkable and a
`structure.yaml`).
- A referenced item that doesn't exist on disk fails the build.

### Links

Link directly to the target Markdown file using a **relative filesystem path**.
The `rewriteMdLinks` remark plugin rewrites these to the correct route at build
time, and **fails the build on broken links**.

```markdown
[Sibling page](./other-page.md)
[Page in another section](../guides/first-party-api.md)
[Cross-product page](../../hotchocolate/index.md)
[Deep link with anchor](./other-page.md#a-section)
[Same-page anchor](#a-section) <!-- just the hash, no file -->
```

- Always point at the `.md` file (e.g. `./cli.md`, not `/docs/.../cli`).
- For a directory/section landing page, link to its `index.md`
(e.g. `./guides/index.md`).
- Same-page anchors are just `#anchor` (no file path).
- Links to **other doc versions** (not present in this repo) or external sites use
absolute URLs, e.g. `https://chillicream.com/docs/hotchocolate/v13/...`.

### Images

Store images under a product namespace in `public/`, **not** next to the docs:

```
public/images/<product>-docs/<name>.webp
```

Reference them with a relative path that resolves **into `public/`**; the
`rewriteMdLinks` plugin rewrites it to a rooted URL (`/images/...`) at build time:

```markdown
![Alt text](../../../public/images/fusion-docs/overview.webp)
```

(Use as many `../` as needed to reach the repo root from the doc's directory.) The
build fails if the referenced file does not exist.

### YouTube videos

Put a YouTube link **alone in its own paragraph**. The `youtubeEmbed` remark
plugin converts it into an embedded player; the link text becomes the play-button
label. A raw Markdown viewer (e.g. GitHub) still shows a clickable link.

```markdown
[Watch the video on YouTube](https://www.youtube.com/watch?v=VIDEO_ID)
```

A YouTube link inside surrounding prose is left as a normal inline link.

### Admonitions

Use GitHub-style alert blockquotes. Supported kinds: `NOTE`, `TIP`, `WARNING`,
`CAUTION`, `EXPERIMENTAL`.

```markdown
> [!WARNING]
> This action cannot be undone.
```

### Diagrams (Mermaid)

Prefer Mermaid over a static image for diagrams (flowcharts, sequence diagrams).
Use a fenced ```mermaid block. Styling (colors, rounded nodes, dimmed lines) is
applied automatically via the theme in `src/mdx-plugins.ts`, so don't hard-code
colors.

````markdown
```mermaid
flowchart LR
Client --> Gateway["Fusion Gateway"]
Gateway --> Service["Products Service"]
```
````

> [!IMPORTANT]
> Keep node labels on a **single line**. Multi-line (`<br/>`) or auto-wrapped
> labels are mis-measured during headless rendering and get clipped at the box
> edge. If a label is long, keep it concise rather than wrapping it.

### MDX gotchas

- **Escape literal curly braces.** Raw `{...}` is parsed as a JavaScript
expression and breaks the build (e.g. format specifiers, placeholders). Write
`\{` and `\}`, or wrap the value in backticks.
- HTML comments (`<!-- ... -->`) are stripped before compilation; don't rely on
them rendering.
- A range of MDX components is available (e.g. `Tabs`, `ExampleTabs`,
`PackageInstallation`); see `mdx-components.tsx` for the full set.
6 changes: 3 additions & 3 deletions website-next/app/blog/[...slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
export const dynamicParams = false;

export function generateStaticParams(): Params[] {
const postParams = listBlogPosts().map<Params>(({ parsed }) => ({
slug: [parsed.year, parsed.month, parsed.day, parsed.slug],
const postParams = listBlogPosts().map<Params>(({ stem }) => ({
slug: [stem],
}));

const summaries = listBlogPostSummaries();
Expand Down Expand Up @@ -125,7 +125,7 @@
{featuredImage ? (
// eslint-disable-next-line @next/next/no-img-element
<img
src={featuredImage}

Check failure

Code scanning / CodeQL

Stored cross-site scripting High

Stored cross-site scripting vulnerability due to
stored value
.
alt=""
loading="eager"
decoding="async"
Expand Down Expand Up @@ -155,7 +155,7 @@
}

function stemForSlug(slug: string[]): string {
return `${slug[0]}-${slug[1]}-${slug[2]}-${slug.slice(3).join("/")}`;
return slug[0];
}

function renderPagination(pageNum: number) {
Expand Down
1 change: 1 addition & 0 deletions website-next/app/docs/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const PRODUCTS = [
{ slug: "strawberryshake", label: "Strawberry Shake" },
{ slug: "nitro", label: "Nitro" },
{ slug: "mocha", label: "Mocha" },
{ slug: "skillz", label: "Skillz" },
];

export default function DocsIndex() {
Expand Down
Empty file removed website-next/content/blog/.gitkeep
Empty file.
Loading
Loading