Fumadocs

Sanity

Official integration for Sanity.

Overview

Fumadocs provide an official integration to simplify setup for Sanity CMS, it brings native live preview experience without compromise on performance.

You can see our Sanity Example on GitHub.

Setup

Assume you already have Sanity configured according to their docs.

Data Types

Run the following command to initialize content types.

npx @fumadocs/cli add sanity/base

Or you can run npx @fumadocs/cli add and browse additional Sanity presets to install.

Register the installed types:

import { docsType, blockContent, callout, card, cards } from '@/lib/sanity/base';

export const schemaTypes = [blockContent, callout, card, cards, docsType];

Content Loader

Install the integration:

npm i @fumadocs/sanity
lib/source.ts
import { dynamicLoader } from 'fumadocs-core/source';
import { createSanitySource } from '@fumadocs/sanity';
// the live preview client
import { sanityFetch } from '@/sanity/lib/live';
// the generated types
import type { Docs } from '@/sanity/types';

const source = dynamicLoader(
  createSanitySource<Docs>({
    sanityFetch,
    docType: 'docs',
  }),
  {
    baseUrl: '/docs',
  },
);

export async function getSource() {
  return source.get();
}

With sanityFetch, <SanityLive /> revalidates queries when content changes, live updates and draft mode work without calling invalidate().

If you enabled Cache Components, call getSource() inside a 'use cache' scope (for example, a cached page) as sanityFetch requires one.

Now render pages with the getSource() function:

app/docs/[[...slug]]/page.tsx
import { notFound } from 'next/navigation';
import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/layouts/docs/page';
import { getSource } from '@/lib/source';
import { CustomPortableText } from '@/components/sanity';

export default async function Page(props: PageProps<'/docs/[[...slug]]'>) {
  const params = await props.params;
  const source = await getSource();
  const page = source.getPage(params.slug);
  if (!page) notFound();

  const { renderToc, body } = await page.data.load();

  return (
    <DocsPage toc={renderToc({ render: (block) => <CustomPortableText value={block} /> })}>
      <DocsTitle>{page.data.title}</DocsTitle>
      <DocsDescription>{page.data.description}</DocsDescription>
      <DocsBody>
        <CustomPortableText value={body!} />
      </DocsBody>
    </DocsPage>
  );
}

Done

Create documents under the docs type in your studio editor, new content will be displayed in the docs route.

How is this guide?

Last updated on