Ariadocs

TanStack Start

Edit on GitHub

Docs pages and an API reference with server functions.

TanStack Start loaders also run in the browser during client navigation. Anything that reads files has to go through a server function.

Docs pages

src/routes/docs/$.tsx
import { createFileRoute, notFound } from "@tanstack/react-router";
import { createServerFn } from "@tanstack/react-start";
import { isMdxNotFound } from "@ariadocs/mdx";
import { MdxClient } from "@ariadocs/mdx/client";
import { docs } from "../../docs";

const getPage = createServerFn({ method: "GET" })
  .inputValidator((slug: string) => slug)
  .handler(async ({ data: slug }) => {
    try {
      const { serialized, frontmatter } = await docs.serialize<{ title: string }>({ slug });
      return { serialized, frontmatter };
    } catch (error) {
      if (isMdxNotFound(error)) throw notFound();
      throw error;
    }
  });

export const Route = createFileRoute("/docs/$")({
  loader: ({ params }) => getPage({ data: params._splat ?? "" }),
  component: DocsPage,
});

function DocsPage() {
  const { serialized, frontmatter } = Route.useLoaderData();
  return (
    <article>
      <h1>{frontmatter.title}</h1>
      <MdxClient serialized={serialized} />
    </article>
  );
}

API reference

src/routes/reference/$operation.tsx
import { createFileRoute } from "@tanstack/react-router";
import { createServerFn } from "@tanstack/react-start";
import { OpenAPI } from "@ariadocs/components";
import { openapi } from "../../openapi";

const getSpec = createServerFn({ method: "GET" }).handler(() => openapi.parse());

export const Route = createFileRoute("/reference/$operation")({
  loader: () => getSpec(),
  component: ReferencePage,
});

function ReferencePage() {
  const api = Route.useLoaderData();
  const { operation } = Route.useParams();
  return (
    <OpenAPI.Root api={api} operationBaseHref="/reference">
      <OpenAPI.Operation id={operation} headingLevel={1} />
    </OpenAPI.Root>
  );
}

openapi.parse() caches its result, so the spec is read once per server process.