Router ルーティング

NocoBase では、プラグインはルーティングを通じてページを登録します。よく使われる 2 つの方法があります:

  • this.router.add() -- 通常のページルートを登録します
  • this.pluginSettingsManager.addMenuItem() + addPageTabItem() -- プラグイン設定ページを登録します

ルーティングの登録は通常、プラグインの load() メソッド内で行います。詳細は Plugin プラグイン をご覧ください。

注意

NocoBase v2 のプラグインでは、ルート登録後にデフォルトで /v2 プレフィックスが付与されます。アクセス時にはこのプレフィックスを含める必要があります。

デフォルトルート

NocoBase には以下のデフォルトルートが登録されています:

名前パスコンポーネント説明
admin/v2/admin/*AdminLayout管理画面ページ
admin.page/v2/admin/:nameAdminDynamicPage動的に作成されるページ
admin.settings/v2/admin/settings/*AdminSettingsLayoutプラグイン設定ページ

ページルート

this.router.add() でページルートを登録します。ページコンポーネントには componentLoader を使用してオンデマンドロードすることを推奨します。これにより、実際にアクセスした時にのみページコードがロードされます。

注意

ページファイルは export default でコンポーネントをエクスポートする必要があります。

// pages/HelloPage.tsx
export default function HelloPage() {
  return <h1>Hello, NocoBase!</h1>;
}

プラグインの load() で登録します:

import { Plugin } from '@nocobase/client-v2';

class MyPlugin extends Plugin {
  async load() {
    this.router.add('hello', {
      path: '/hello',
      // オンデマンドロード、/v2/hello にアクセスした時にのみモジュールをロード
      componentLoader: () => import('./pages/HelloPage'),
    });
  }
}

router.add() の第 1 引数はルート名で、ドット . で親子関係を表現できます。例えば root.homeroot の子ルートを意味します。

コンポーネント内では、ctx.router.navigate('/hello') でこのルートにナビゲートできます。

import { useFlowContext } from '@nocobase/flow-engine';
import { Button } from 'antd';

export default function SomeComponent() {
  const ctx = useFlowContext();
  return (
    <Button onClick={() => ctx.router.navigate('/hello')}>
      Go to Hello Page
    </Button>
  );
}

詳細は Component コンポーネント開発 のルーティングセクションをご覧ください。

ネストされたルート

ドット記法による命名でネストを実現し、親ルートは <Outlet /> で子ルートの内容をレンダリングします:

import { Outlet } from 'react-router-dom';

class MyPlugin extends Plugin {
  async load() {
    // 親ルート、element で直接レイアウトを記述
    this.router.add('root', {
      element: (
        <div>
          <nav>ナビゲーションバー</nav>
          <Outlet />
        </div>
      ),
    });

    // 子ルート、componentLoader でオンデマンドロード
    this.router.add('root.home', {
      path: '/', // -> /v2/
      componentLoader: () => import('./pages/HomePage'),
    });

    this.router.add('root.about', {
      path: '/about', // -> /v2/about
      componentLoader: () => import('./pages/AboutPage'),
    });
  }
}

動的パラメータ

ルートパスは動的パラメータに対応しています:

this.router.add('root.user', {
  path: '/user/:id', // -> /v2/user/:id
  componentLoader: () => import('./pages/UserPage'),
});

コンポーネント内では、ctx.route.params で動的パラメータを取得できます:

import { useFlowContext } from '@nocobase/flow-engine';

export default function UserPage() {
  const ctx = useFlowContext();
  const { id } = ctx.route.params; // 動的パラメータ id を取得
  return <h1>User ID: {id}</h1>;
}

詳細は Component コンポーネント開発 のルーティングセクションをご覧ください。

componentLoader と element の違い

  • componentLoader(推奨):オンデマンドロード。ページコンポーネントに適しており、ページファイルは export default が必要です
  • element:JSX を直接渡します。レイアウトコンポーネントや非常に軽量なインラインページに適しています

ページ自体の依存関係が重い場合は、componentLoader を優先して使用することを推奨します。

プラグイン設定ページ

this.pluginSettingsManager でプラグイン設定ページを登録します。登録は 2 ステップで行います -- まず addMenuItem() でメニューエントリを登録し、次に addPageTabItem() で実際のページを登録します。設定ページは NocoBase の「プラグイン設定」メニューに表示されます。

20260403155201

import { Plugin, Application } from '@nocobase/client-v2';

export class HelloPlugin extends Plugin<any, Application> {
  async load() {
    // メニューエントリを登録
    this.pluginSettingsManager.addMenuItem({
      key: 'hello',
      title: this.t('Hello 設定'),
      icon: 'ApiOutlined', // Ant Design アイコン名、参考:https://5x.ant.design/components/icon
    });

    // ページを登録(key が 'index' の場合、メニューのルートパスにマッピング)
    this.pluginSettingsManager.addPageTabItem({
      menuKey: 'hello',
      key: 'index',
      title: this.t('Hello 設定'),
      componentLoader: () => import('./settings/HelloSettingPage'),
    });
  }
}

登録後、アクセスパスは /admin/settings/hello となります。メニューにページが 1 つしかない場合、上部のタブバーは自動的に非表示になります。

複数タブの設定ページ

設定ページに複数のサブページが必要な場合、同じ menuKey で複数の addPageTabItem を登録します -- 上部にタブバーが自動的に表示されます:

import { Plugin, Application } from '@nocobase/client-v2';

class HelloPlugin extends Plugin<any, Application> {
  async load() {
    // メニューエントリを登録
    this.pluginSettingsManager.addMenuItem({
      key: 'hello',
      title: this.t('HelloWorld'),
      icon: 'ApiOutlined',
    });

    // タブ 1:基本設定(key が 'index'、/admin/settings/hello にマッピング)
    this.pluginSettingsManager.addPageTabItem({
      menuKey: 'hello',
      key: 'index',
      title: this.t('基本設定'),
      componentLoader: () => import('./settings/GeneralPage'),
    });

    // タブ 2:詳細設定(/admin/settings/hello/advanced にマッピング)
    this.pluginSettingsManager.addPageTabItem({
      menuKey: 'hello',
      key: 'advanced',
      title: this.t('詳細設定'),
      componentLoader: () => import('./settings/AdvancedPage'),
    });
  }
}

addMenuItem パラメータ

フィールド必須説明
keystringはいメニューの一意識別子。. を含めることはできません
titleReactNodeいいえメニュータイトル
iconstring | ReactNodeいいえメニューアイコン。文字列の場合は組み込みの Icon でレンダリングされます
sortnumberいいえソート値。小さいほど前に表示されます。デフォルトは 0
showTabsbooleanいいえ上部タブバーを表示するかどうか。デフォルトではページ数に応じて自動判定
hiddenbooleanいいえナビゲーションエントリを非表示にするかどうか

addPageTabItem パラメータ

フィールド必須説明
menuKeystringはい所属メニューの keyaddMenuItemkey に対応します
keystringはいページの一意識別子。'index' はデフォルトページを意味し、メニューのルートパスにマッピングされます
titleReactNodeいいえページタイトル(タブに表示されます)
componentLoaderFunctionいいえ遅延ロードページコンポーネント(推奨)
ComponentComponentいいえコンポーネントを直接渡します(componentLoader と択一)
sortnumberいいえソート値。小さいほど前に表示されます
hiddenbooleanいいえタブで非表示にするかどうか
linkstringいいえ外部リンク。設定するとタブクリック時に外部アドレスに遷移します

関連リンク