Hanzo
Quick StartIntegrationsOpenAPI

<APIPage />

The component for rendering OpenAPI docs content

Overview

Fumadocs OpenAPI uses a <APIPage /> component to render page contents.

When customising it, the options are split into server/client configs.

import { openapi } from '@/lib/openapi';
import { createAPIPage } from '@hanzo/docs-openapi/ui';
import client from './api-page.client';

export const APIPage = createAPIPage(openapi, {
  client,
  // server config
});

Generate Code Usages

Generate code usage examples for each API endpoint.

import {
  createCodeUsageGeneratorRegistry,
  type CodeUsageGenerator,
} from '@hanzo/docs-openapi/requests/generators';
import { registerDefault } from '@hanzo/docs-openapi/requests/generators/all';

export const codeUsages = createCodeUsageGeneratorRegistry();

// include defaults
registerDefault(codeUsages);

// add custom generators
codeUsages.add('custom-id', {
  label: 'My Example',
  lang: 'js',
  generate(url, data, { mediaAdapters }) {
    // request data
    console.log(url, data);

    return 'const response = "hello world";';
  },
});

Pass the registry to both client & server configs:

import { openapi } from '@/lib/openapi';
import { createAPIPage } from '@hanzo/docs-openapi/ui';
import { codeUsages } from '@/lib/openapi/code-usage';
import client from './api-page.client';

export const APIPage = createAPIPage(openapi, {
  client,
  codeUsages,
});

In addition, you can also specify code samples via OpenAPI schema.

paths:
  /plants:
    get:
      x-codeSamples:
        - lang: js
          label: JavaScript SDK
          source: |
            const planter = require('planter');
            planter.list({ unwatered: true });

Internationalization

Assuming you have configured Internationalization at UI level:

import { defineI18n } from '@hanzo/docs-core/i18n';
import { defineI18nUI } from '@hanzo/docs-ui/i18n';
import { defineI18nOpenAPI } from '@hanzo/docs-openapi/i18n';

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

export let i18nUI = defineI18nUI(i18n, {
  cn: { displayName: 'Chinese' },
});

i18nUI = defineI18nOpenAPI(i18nUI, {
  cn: {
    titleRequestBody: '請求正文',
  },
});

Media Adapters

You can create a media adapter to support other media types in API pages, a media adapter implements:

  • Converting value into fetch() body compatible with corresponding media type.
  • Generate code example based on different programming language/tool.

Put your media adapters in a separate file.

import type { MediaAdapter } from '@hanzo/docs-openapi';

export const mediaAdapters: Record<string, MediaAdapter> = {
  // example: custom `application/json
  'application/json': {
    encode(data) {
      return JSON.stringify(data.body);
    },
    // returns code that inits a `body` variable, used for request body
    generateExample(data, ctx) {
      if (ctx.lang === 'js') {
        return `const body = "hello world"`;
      }

      if (ctx.lang === 'python') {
        return `body = "hello world"`;
      }

      if (ctx.lang === 'go' && 'addImport' in ctx) {
        ctx.addImport('strings');

        return `body := strings.NewReader("hello world")`;
      }
    },
  },
};

Pass the adapter to both client & server configs.

import { openapi } from '@/lib/openapi';
import { createAPIPage } from '@hanzo/docs-openapi/ui';
import { mediaAdapters } from '@/lib/openapi/media';
import client from './api-page.client';

export const APIPage = createAPIPage(openapi, {
  client,
  mediaAdapters,
});

How is this guide?

Last updated on

On this page