コンテンツへスキップ
Fumadocs

createGraphQLPage()

GraphQL ドキュメントのコンテンツをレンダリングするコンポーネント

概要

Fumadocs GraphQL は、ページコンテンツのレンダリングに <GraphQLPage /> コンポーネントを使用します。このコンポーネントはクライアントコンポーネントにする必要があります。

components/api-page.tsx
'use client';
import { createGraphQLPage } from '@fumadocs/graphql/ui';

export const GraphQLPage = createGraphQLPage({
  // 設定
});

プレイグラウンド

エンドポイントを設定すると、オペレーションページにプレイグラウンドが表示されます。読者はオペレーションを編集し、変数をフォームまたは JSON で入力して、必要なヘッダーを付けて送信できます。

components/api-page.tsx
'use client';
import { createGraphQLPage } from '@fumadocs/graphql/ui';

export const GraphQLPage = createGraphQLPage({
  playground: {
    url: 'https://api.example.com/graphql',
    // ユーザーによるエンドポイントURLの編集を許可する (デフォルト: true)
    allowUrlEdit: false,
    // プレイグラウンドから送信するリクエストのデフォルトヘッダー
    headers: {
      'X-Client-Name': 'docs',
    },
  },
});

headers にシークレットを含めないでください。ヘッダーはブラウザに送信され、コードサンプルにも表示されるほか、エンドポイントのオリジンごとにブラウザのローカルストレージに保存されます。

クエリとミューテーションは HTTP POST で送信されます。fetcher を置き換えれば、たとえばリクエストをプロキシ経由で送信することもできます。

components/api-page.tsx
'use client';
import { createGraphQLPage } from '@fumadocs/graphql/ui';

export const GraphQLPage = createGraphQLPage({
  playground: {
    async fetcher(request) {
      const start = performance.now();
      const res = await fetch('/api/proxy', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', ...request.headers },
        body: JSON.stringify({ query: request.query, variables: request.variables }),
      });

      return {
        type: 'response',
        status: res.status,
        time: performance.now() - start,
        body: await res.text(),
        contentType: res.headers.get('Content-Type') ?? '',
        // 省略可能。Headers タブに表示されます
        headers: Array.from(res.headers),
      };
    },
  },
});

また、render を使うとプレイグラウンドの UI 全体を置き換えることもできます。この場合、シグネチャバーの代わりに表示されます。

components/api-page.tsx
'use client';
import { createGraphQLPage } from '@fumadocs/graphql/ui';

export const GraphQLPage = createGraphQLPage({
  playground: {
    render({ kind, name, operation }) {
      return <div>my playground</div>;
    },
  },
});

サブスクリプション

サブスクリプションのページでは、プレイグラウンドが subscriptionUrl をサブスクライブし、受信したイベントをログに出力します。デフォルトでは、url のスキームを ws(s):// に置き換えたものが使用されます。

subscriptionUrlプロトコル
ws://、wss://graphql-ws(graphql-transport-ws)
http://、https://GraphQL over SSE(distinct connections モード)
components/api-page.tsx
'use client';
import { createGraphQLPage } from '@fumadocs/graphql/ui';

export const GraphQLPage = createGraphQLPage({
  playground: {
    url: 'https://api.example.com/graphql',
    // 同じエンドポイントで GraphQL over SSE を使用
    subscriptionUrl: 'https://api.example.com/graphql',
  },
});

ブラウザーの制限

ブラウザーでは WebSocket 接続のヘッダーを設定できないため、graphql-ws はヘッダーを代わりに connection_init のペイロードに含めて送信します。

コードサンプル

リクエストの例は GraphQL で表示されるほか、cURL、JavaScript、Go、Python、Java、C#、Rust のコードとしても表示されます。これらのコードは playground.headers を付けて playground.url(未設定の場合はプレースホルダー)にリクエストを送信します。プレイグラウンドでも、編集中のリクエストについて同じコードが表示されます。サブスクリプションのページでは、例は GraphQL でのみ表示されます。

codeUsages でジェネレーターを追加したり、デフォルトのジェネレーターを削除したりできます。

components/api-page.tsx
'use client';
import {
  createCodeUsageGeneratorRegistry,
  createGraphQLPage,
  registerDefaultCodeUsages,
} from '@fumadocs/graphql/ui';

// ゼロから始める場合は、デフォルトを登録しないでください
const codeUsages = registerDefaultCodeUsages(createCodeUsageGeneratorRegistry());

// デフォルト: curl、js、go、python、java、csharp、rust
codeUsages.remove('java');
codeUsages.add('graphql-request', {
  label: 'graphql-request',
  lang: 'js',
  generate({ url, query, variables = {}, headers }) {
    return `import { request } from 'graphql-request';

const data = await request(${JSON.stringify(url)}, ${JSON.stringify(query)}, ${JSON.stringify(variables)}, ${JSON.stringify(headers)});`;
  },
});

export const GraphQLPage = createGraphQLPage({ codeUsages });

プロパティ

型

相互リンク

型ページは、型ページ同士およびオペレーションへ自動的にリンクされます。オペレーションページでは読者がページを離れることはなく、型はスキーマ UI 内で開かれます。

リンクを独自に解決することもできます。

components/api-page.tsx
'use client';
import { createGraphQLPage } from '@fumadocs/graphql/ui';

export const GraphQLPage = createGraphQLPage({
  typeLinks(name) {
    return `/docs/types/${name}`;
  },
  operationLinks(kind, name) {
    return `/docs/${kind}/${name}`;
  },
});

専用のページを持たない型やオペレーションには undefined を返してください。

カスタムレイアウト

オペレーションページと型ページのレイアウトをカスタマイズできます。

components/api-page.tsx
'use client';
import { createGraphQLPage } from '@fumadocs/graphql/ui';

export const GraphQLPage = createGraphQLPage({
  content: {
    renderOperationLayout(slots) {
      return (
        <div className="flex flex-col gap-6">
          {slots.header}
          {slots.playground}
          {slots.description}
          {slots.deprecated}
          {slots.arguments}
          {slots.returns}
          {slots.example}
        </div>
      );
    },
  },
});
スロットレンダリング内容
headerタイトル(複数の項目を含むページのみ)
playgroundQUERY customer(id: ID!): Customer のようなシグネチャ、そのディレクティブ、およびプレイグラウンド
descriptionオペレーションの説明
deprecated非推奨の理由
arguments引数
returns戻り値の型とそのフィールド
exampleリクエストとレスポンスの例(幅の広いページではオペレーションの横に表示)

スキーマ UI

型のレンダリング方法をカスタマイズします。

components/api-page.tsx
'use client';
import { createGraphQLPage } from '@fumadocs/graphql/ui';

export const GraphQLPage = createGraphQLPage({
  schemaUI: {
    render(options, ctx) {
      // 完全カスタムのスキーマレンダラー
      return <ctx.SchemaUI {...options} />;
    },
  },
});

国際化

UI レベルで国際化を設定済みであることを前提とします。

layout.shared.tsx
import { defineI18n } from 'fumadocs-core/i18n';
import { uiTranslations } from 'fumadocs-ui/i18n';
import { graphqlTranslations } from '@fumadocs/graphql/i18n';

const i18n = defineI18n({
  languages: ['en', 'cn'],
  defaultLanguage: 'en',
});

export const translations = i18n
  .translations()
  .extend(uiTranslations())
  .extend(graphqlTranslations())
  .add({
    cn: {
      displayName: 'Chinese',
      'Arguments(operation page)': '参数',
    },
  });

詳しくは翻訳を参照してください。

シンタックスハイライト

GraphQL ページでは Shiki を使ってコードブロックをハイライトします。カスタマイズするには、ハイライターを渡してください。

components/api-page.tsx
'use client';
import { createGraphQLPage } from '@fumadocs/graphql/ui';
import { highlighter } from '@/lib/highlighter';

export const GraphQLPage = createGraphQLPage({ highlighter });

カスタムコンポーネント

見出し、コードブロック、Markdown のデフォルトコンポーネントを上書きできます。

components/api-page.tsx
'use client';
import { createGraphQLPage } from '@fumadocs/graphql/ui';

export const GraphQLPage = createGraphQLPage({
  components: {
    Heading({ id, depth, ...props }) {
      const Tag = `h${depth}` as const;
      return <Tag id={id} {...props} />;
    },
    CodeBlock({ lang, code }) {
      return <pre data-lang={lang}>{code}</pre>;
    },
  },
});

UIのカスタマイズ

用意されているオプションでは対応できないカスタマイズが必要な場合は、Fumadocs CLIを使ってUIをコードベースにインストールできます。

完全な UI

ヘッドレスレイヤーをベースに構築された、GraphQL ページの UI 一式です。

npx @fumadocs/cli add graphql/page

これにより <GraphQLPage /> 自体がインストールされるため、components/api-page.tsx は不要になります。<GraphQLPage /> のインポートを次のように更新してください:

import { GraphQLPage } from '@/components/api-page'; 
import { GraphQLPage } from '@/components/graphql/page'; 

パーツ

編集したいパーツだけをインストールし、components を通じて渡してください。プレイグラウンドには components 内のスロットがありません。インストールした graphql/operation でレンダリングされるほか、playground.render から <OperationPlayground /> を返すこともできます。

コンポーネント内容
graphql/operationオペレーション (引数と例を含む)
graphql/type-docs名前付きの型 (フィールドと使用箇所を含む)
graphql/schema-ui型、引数、フィールドの詳細
graphql/playgroundインタラクティブなプレイグラウンド
components/api-page.tsx
'use client';
import { createGraphQLPage } from '@fumadocs/graphql/ui';
import { Operation } from '@/components/graphql/operation';
import { TypeDocs } from '@/components/graphql/type-docs';

export const GraphQLPage = createGraphQLPage({
  components: {
    Operation,
    TypeDocs,
  },
});

How is this guide?

最終更新日