React-admin(リアクトアドミン)は、REST APIやGraphQL APIに接続する管理画面を、Reactのコンポーネントを並べて組み立てるフレームワークです。フランスのmarmelab社が開発し、ライセンスはMITで商用利用も無料です。2026年10月28日時点のnpm最新版は5.15.5(10月19日公開)で、一覧・編集・作成・ダッシュボード・権限・API Platformのコードはこの版で型検査とビルドを通しています(独自dataProviderは抜粋、Next.jsの例は公式手順の引用です)。雛形の作り方、DataTableでの一覧、dataProviderでのAPI接続とつまずきやすい総件数ヘッダー、API PlatformやGraphQLとの組み合わせ、無償で使える権限制御、Enterprise Editionの料金までを順に扱います。
まとめ:React-adminの要点
- 正体:APIから管理画面を組むReact製フレームワーク。中核はヘッドレスの
ra-coreで、標準のUIはMaterial UI(v5.15.0でMUI v9に対応)。 - 始め方:
npx create-react-admin@latest my-adminでVite構成の雛形ができる。オプションを省くとdataProviderはnoneで、--data-provider json-serverを選ぶと接続先はJSONPlaceholderになる。 - 一覧:新規開発は
DataTable(5.8.0で追加)で書く。Datagridは後方互換のため残っている。 - API接続:
ra-data-simple-restはContent-Range、ra-data-json-serverはX-Total-Countで総件数を読む。別オリジンならCORSでこのヘッダーを公開しないと一覧がエラーになる。 - API Platform:
@api-platform/adminのHydraAdminにエントリポイントを渡すと画面を推測生成する。Symfony版のディストリビューションには最初から入っている。 - 権限と料金:
authProvider.canAccessによる権限制御は5.3.0から無償版に入った。ロール定義と権限対応の部品をまとめたRBACモジュールやリアルタイム更新は有償のEnterprise Edition(年払いで月額換算145ユーロから)。
React-adminの仕組み:ra-coreと画面コンポーネント
React-adminは、APIとの通信をdataProvider、ログインと権限をauthProviderという2つのアダプターに閉じ込め、画面側は<List>や<Edit>といったコンポーネントで宣言します。画面は「一覧を取る」「1件更新する」といった抽象的な呼び出ししかしないので、バックエンドを差し替えても画面のコードはほぼ変わりません。前身はadmin-on-restという名前で公開されていたライブラリで、今もこの名前で検索されることがあります。
依存ライブラリの版(5.15.5時点)
公式のArchitectureのページは、react-adminの中核を「主にフックで構成されるヘッドレスライブラリra-core」と説明しています。その上に、Material UIで描画するra-ui-materialuiが載る二層構造です。2026年10月28日にnpm i [email protected]を実行して解決された版は次のとおりです。
| 役割 | パッケージ | 許容範囲(peer) | 実際に入った版 |
|---|---|---|---|
| UI | @mui/material | ^5.16.12 || ^6.0.0 || ^7.0.0 || ^9.0.0 |
9.5.0 |
| フォーム | react-hook-form | ^7.72.0 | 7.91.0 |
| 取得とキャッシュ | @tanstack/react-query | ^5.83.0 | 5.105.0 |
| ルーティング | react-router | ^6.28.1 または ^7.1.1 | 7.18.5 |
| React | react / react-dom | ^18.0.0 または ^19.0.0 | 19 |
MUIはv5・v6・v7・v9のどれでも受け付けます。既存プロジェクトにMUI v6やv7が入っていても、react-adminのためにMUIを上げる必要はありません。MUI自体の導入とテーマの書き方はMaterial UIとは:v9系の導入からGrid・テーマ設定までコード付きで解説で扱っています。
Material UI以外のUI:ra-coreとShadcn Admin Kit
以前は「React-adminはMUI固定」と言われていましたが、2026年時点では当てはまりません。公式サイトはMaterial UI版と並べてshadcn/ui系のShadcn Admin Kitを案内しており、ra-coreのフックだけを使えば任意のUIキットで画面を組めます。ただしドキュメントとサンプルの大半はMUI版が前提なので、MUI以外を選ぶと自分で書く部品は増えます。
create-react-adminでの雛形作成とオプション
公式チュートリアルは、スキャフォールドツールcreate-react-adminから始めます。5.15.5では、質問に答えて選ぶには--interactiveが必要です。付けずに名前だけ渡すと質問は出ず、dataProviderとauthProviderはnone、リソースなしの空の雛形ができます。下の例は検証した版に合わせて@5.15.5で固定しています。最新版で作るなら@latestに置き換えます。
# 対話モード(質問に答えて選ぶ)
npx [email protected] my-admin --interactive
# 非対話で作る例:json-server形式のAPI+テスト用ログイン+2リソース
npx [email protected] my-admin --data-provider json-server --auth-provider local-auth-provider --resource posts --resource comments --install npm
cd my-admin
npm run dev
| オプション | 指定できる値(5.15.5の–help) |
|---|---|
--data-provider |
fakerest / simple-rest / json-server / supabase / none |
--auth-provider |
local-auth-provider / none |
--resource |
リソース名(複数回指定可・skipで省略) |
--install |
yarn / npm / bun / pnpm / skip |
上の非対話の例で生成すると、.envにVITE_JSON_SERVER_URL=https://jsonplaceholder.typicode.comが書かれ、公開のダミーAPIにつながった状態で起動します。App.tsxの各リソースはListGuesser・EditGuesser・ShowGuesserになっていて、APIの応答から列を推測して表示します。テスト用ログインはjanedoeまたはjohndoe、パスワードはpasswordです。生成されたauthProvider.tsには「テスト専用で本番では使わない」とコメントがあるので、本番では自社の認証基盤につなぎ替えます。
注意点が1つあります。生成されたpackage.jsonは@mui/materialを^7.0.1で指定しており、npm i react-adminで既存プロジェクトに足した場合(MUI 9.5.0が入る)と主要版がずれます。どちらも動作範囲内ですが、MUIのドキュメントを読むときは自分のプロジェクトの版をnpm ls @mui/materialで確かめてください。
一覧・編集・作成画面の実装
Guesserは確認用で、実際の画面はコンポーネントを自分で書いて置き換えます。下のコードは、記事(posts)の一覧・編集・作成画面を作り、著者(users)は参照先としてだけ登録する例です。tsc --noEmit(TypeScript 5.9.3・strict)とVite 8.3.5のビルドが通ることを確認しています。
一覧:DataTableとReferenceField
import {
List, DataTable, ReferenceField, ReferenceInput, TextInput, EditButton, type RaRecord,
} from "react-admin";
interface Post extends RaRecord { title: string; userId: number; }
// alwaysOn を付けた検索欄は常に表示、ほかは「フィルタを追加」から出す
const postFilters = [
<TextInput key="q" source="q" label="検索" alwaysOn />,
<ReferenceInput key="u" source="userId" reference="users" />,
];
export const PostList = () => (
<List<Post> filters={postFilters} sort={{ field: "id", order: "DESC" }}>
<DataTable>
<DataTable.Col source="id" />
<DataTable.Col source="title" />
<DataTable.Col source="userId" label="著者">
<ReferenceField source="userId" reference="users" />
</DataTable.Col>
<DataTable.Col><EditButton /></DataTable.Col>
</DataTable>
</List>
);
<List>がデータ取得・並べ替え・ページ送り・フィルタの状態を持ち、<DataTable>が表を描きます。<ReferenceField>は外部キーuserIdから著者を引いて表示し、表示する項目は<Resource name="users" recordRepresentation="name" />で決めます。List<Post>の型引数はList側の型付けで、子コンポーネントでuseListContextやuseRecordContextを呼ぶときは、そちらにも<Post>を渡します(既定の型はany)。
2025年4月30日の5.8.0でDataTableが入り、Datagridのページには「新規プロジェクトにはDataTableを推奨し、Datagridは後方互換のため引き続き提供する」とあります。移行用のcodemodも用意されています。日本語のチュートリアル記事の多くは<Datagrid>と<TextField>で書かれているので、写すときは列をDataTable.Colに読み替えてください。
編集・作成:SimpleFormとReferenceInput
import { Edit, Create, SimpleForm, TextInput, ReferenceInput, required, useRecordContext } from "react-admin";
const PostTitle = () => {
const record = useRecordContext<Post>();
return <span>{record ? record.title : ""}</span>;
};
export const PostEdit = () => (
<Edit<Post> title={<PostTitle />}>
<SimpleForm>
<TextInput source="title" validate={required()} />
<ReferenceInput source="userId" reference="users" />
</SimpleForm>
</Edit>
);
export const PostCreate = () => (
<Create<Post>>
<SimpleForm>
<TextInput source="title" validate={required()} />
<ReferenceInput source="userId" reference="users" />
</SimpleForm>
</Create>
);
<Edit>はdataProviderのgetOneで1件を読み、保存時にupdateを呼びます。フォームの状態管理はreact-hook-formが担います。validateにはReact-adminの検証関数(required()やminLength()など。正しければundefined、誤りならエラーメッセージを返す)を渡し、独自の入力部品はuseInputで作ります。検証のタイミングなど細部はReact Hook Formとは?使い方とv7の書き方・検証タイミング【7.91対応】が詳しいです。
ダッシュボード:Adminのdashboardプロパティ
ログイン直後のトップ画面は、<Admin>のdashboardに任意のコンポーネントを渡すと差し替わります。集計値を出したいときは、ダッシュボードの中でuseGetListなどのフックを使ってdataProvider経由で取ります。
import { Admin, Resource } from "react-admin";
const Dashboard = () => <h1>ダッシュボード</h1>;
export const App = () => (
<Admin dataProvider={dataProvider} authProvider={authProvider} dashboard={Dashboard}>
<Resource name="posts" list={PostList} edit={PostEdit} create={PostCreate} />
<Resource name="users" recordRepresentation="name" />
</Admin>
);
dataProviderによるAPI接続
dataProviderはgetList・getOne・getMany・getManyReference・create・update・updateMany・delete・deleteManyの9メソッドを持つオブジェクトです。既製品を使うか、APIに合わせて自作します。
ra-data-simple-restとra-data-json-serverの違い
公式が提供するREST向けの代表的な2つは、URLの組み立て方と総件数の読み方が違います。ローカルにHTTPサーバーを立て、どちらも2ページ目(1ページ10件)・idの降順・q=xでgetListを呼んで、届いたリクエストを記録しました。
| 項目 | ra-data-simple-rest | ra-data-json-server |
|---|---|---|
| ページ指定 | range=[10,19] |
_start=10&_end=20 |
| 並べ替え | sort=["id","DESC"] |
_sort=id&_order=DESC |
| 絞り込み | filter={"q":"x"} |
q=x |
| 総件数 | Content-Range: posts 0-9/42 |
X-Total-Count: 42 |
総件数のヘッダーが無い応答を返すと、どちらも一覧の取得がエラーになります。simple-restの場合のメッセージは「The Content-Range header is missing in the HTTP Response.」で始まり、「CORSを使っているならAccess-Control-Expose-HeadersにContent-Rangeを宣言したか」と続きます。管理画面とAPIのオリジンが違うと、サーバーがヘッダーを返していてもブラウザのJavaScriptからは読めません。
Content-Range: posts 0-9/42
Access-Control-Expose-Headers: Content-Range
上はsimple-restを使うときにAPIサーバーが返すレスポンスヘッダーの例です。Content-Rangeを返せないAPIなら、第3引数でX-Total-Countに切り替えます。
import simpleRestProvider from "ra-data-simple-rest";
const dataProvider = simpleRestProvider("https://api.example.com", undefined, "X-Total-Count");
第3引数に"X-Total-Count"を渡すと、X-Total-Count: 42だけを返すサーバーでも総件数42を読めることを確かめました。この場合もCORSではX-Total-Countを公開します(ra-data-simple-restのREADME)。
独自APIに合わせたdataProviderの実装
一覧が{ items, total }のような独自形式で返るAPIなら、dataProviderを自分で書きます。型DataProviderを付けておくと、9メソッドのどれかを書き忘れたときにtscがエラー(TS2741: Property ‘deleteMany’ is missing)で止めてくれます。
// 抜粋:残り7メソッドを実装すると型検査が通る(このままでは TS2740)
// filter の変換も省いているので、一覧の検索欄・絞り込みはこのままでは効かない
import { fetchUtils, type DataProvider } from "react-admin";
const apiUrl = "https://api.example.com";
export const customProvider: DataProvider = {
getList: async (resource, { pagination, sort }) => {
const { page = 1, perPage = 10 } = pagination ?? {};
const query = new URLSearchParams({
page: String(page), limit: String(perPage),
sort: sort?.field ?? "id", order: sort?.order ?? "ASC",
});
const { json } = await fetchUtils.fetchJson(`${apiUrl}/${resource}?${query}`);
return { data: json.items, total: json.total };
},
getOne: async (resource, { id }) => {
const { json } = await fetchUtils.fetchJson(`${apiUrl}/${resource}/${id}`);
return { data: json };
},
// getMany・getManyReference・create・update・updateMany・delete・deleteMany も同じ形で実装する
};
getListとgetManyReferenceは{ data, total }、それ以外は{ data }を返します。総件数を数えるのが重いAPIなら、totalを省いてpageInfo: { hasPreviousPage, hasNextPage }を返す部分ページネーションも使え、標準のページ送りがそれに合わせて表示を切り替えます(Writing A Data Provider)。ReferenceFieldは表示中の行の外部キーをまとめてgetManyに渡すので、getManyを1件ずつのgetOneの繰り返しで書くと、1画面で件数分のリクエストが飛びます。APIにID一括取得のエンドポイントを用意しておくのが無難です。
GraphQL接続:ra-data-graphql-simpleとgraphqlの版
GraphQLのバックエンドがallPostsやupdatePostといった命名規約に沿っているなら、ra-data-graphql-simpleが使えます。起動時にイントロスペクションでスキーマを読み、規約に合うクエリとミューテーションへ9メソッドを自動で割り当てます。内部ではApollo Client 3系を使います。
導入時の落とし穴はgraphqlパッケージの版です。5.15.5のra-data-graphql-simpleはpeerDependenciesがgraphql ^15.6.0で、npm i ra-data-graphql-simple graphql@16はERESOLVEで止まりました(npm 11.17.0)。土台のra-data-graphqlは^15.6.0 || ^16を受け付けるので、既にgraphql 16系が入っているプロジェクトでは、ra-data-graphqlの上に自分でクエリ組み立て関数を書くほうが衝突しません。スキーマやリゾルバの基本はGraphQLとは?読み方・REST APIとの違いとクエリ・リゾルバの書き方をわかりやすく解説を参照してください。
API Platform連携:HydraAdminでの推測生成とCORS設定
PHPのAPI Platformと組み合わせる場合は、API Platform側が配布する@api-platform/adminを使います。2026年10月時点の最新は4.0.9(2026年2月27日公開)で、依存にreact-admin ^5.8.3を持つReact-adminの上の層です。APIのドキュメント(HydraまたはOpenAPI)を解析し、全リソースの一覧・作成・編集画面を推測して生成します。
import { HydraAdmin, OpenApiAdmin } from "@api-platform/admin";
// Hydra のエントリポイントを渡すだけで全リソースの画面ができる
export const ApiAdmin = () => <HydraAdmin entrypoint="https://localhost" />;
// OpenAPI の場合はドキュメントの場所とAPIの場所を別々に渡す
export const ApiAdminOpenApi = () => (
<OpenApiAdmin docEntrypoint="https://localhost/docs.jsonopenapi" entrypoint="https://localhost" />
);
API Platform Adminのgetting startedによると、API PlatformのSymfony版ディストリビューションを使っているなら管理画面はインストール済みで、アプリの/adminを開くだけで表示されます。手で入れる場合の手順は、create-react-adminで雛形を作ってからnpm install @api-platform/adminです。
動かないときに最初に見るのはCORSです。Symfony版ではapi/.envのCORS_ALLOW_ORIGIN(既定は^https?://localhost:?[0-9]*$)を管理画面のドメインに合わせます。Symfonyに自分でAPI Platform Coreを入れた構成では、NelmioCorsBundleの設定でLinkヘッダーを公開する必要があります。Hydraのドキュメントの場所はLinkヘッダーで知らされるため、これが読めないと画面の推測生成そのものが始まりません。推測された画面はListGuesserなどと同じ扱いで、項目を絞りたい画面だけReact-adminのコンポーネントで書き直せます。
ログインと権限:authProviderとcanAccess
認証はauthProviderのlogin・logout・checkAuth・checkErrorで実装し、権限はcanAccessで返します。canAccessは2024年10月17日の5.3.0で無償版に入りました(v5.3.0のリリースノート)。それ以前の「権限管理は有償版だけ」という説明は古くなっています。
import { CanAccess, type AuthProvider } from "react-admin";
// 学習用:ユーザー名だけでロールを決め、パスワードも検証しない。
// 本番ではAPI側で認証・認可を必ず行う(画面の出し分けはAPIを守らない)
export const authProvider: AuthProvider = {
login: async ({ username }) => {
localStorage.setItem("role", username === "admin" ? "admin" : "editor");
},
logout: async () => { localStorage.removeItem("role"); },
checkAuth: async () => { if (!localStorage.getItem("role")) throw new Error("not logged in"); },
checkError: async () => {},
// 編集者は posts を削除できない。それ以外はすべて許可
canAccess: async ({ action, resource }) =>
localStorage.getItem("role") === "admin" || !(resource === "posts" && action === "delete"),
};
// 任意の領域を権限で出し分ける
export const AdminOnly = () => (
<CanAccess action="delete" resource="posts"><p>管理者だけに見える領域</p></CanAccess>
);
公式のPermissionsのページによると、<List>・<Create>・<Edit>・<Show>は描画前にcanAccessを呼び、<EditButton>や<DeleteButton>などは許可がないと表示されません。canAccessがエラーを返すと/accessControlErrorの画面へ移ります。
列や入力項目の出し分けも無償版で書けます。DataTableのAccess Controlの節は、権限で隠したい列を<CanAccess>で囲む方法を示しており、フォームの項目はuseCanAccessの結果で条件分岐できます。有償の@react-admin/ra-rbacが足すのは、ロール・グループ・ワイルドカード・明示的な拒否を使った権限定義と、権限を自動で確認する版のDatagridやSimpleFormです。「給与の列だけ隠す」程度なら無償版で十分で、ロールと画面の組み合わせが数十に増えて手書きの条件分岐を保守しきれなくなったら有償版を検討します。またcanAccessはページを描くたびに呼ばれるので、毎回サーバーへ問い合わせると画面遷移が遅れます。権限はログイン時に取得して手元に持つのが公式の推奨です。
Next.jsへの組み込み:ssr: falseでのクライアント描画
React-adminは「クライアントで描画するSingle-Page Application」として設計されており、react-routerやemotionなどクライアント専用のライブラリを含みます。公式のNext.js統合手順は、App Routerで管理画面をクライアントコンポーネントにし、next/dynamicのサーバー描画を切って読み込む方法です。
"use client";
import dynamic from "next/dynamic";
const AdminApp = dynamic(() => import("./AdminApp"), {
ssr: false, // react-router 関連のエラーを避けるために必要
});
export default AdminApp;
つまり「Next.jsで使えない」のではなく、「Next.jsの中に置けるが、管理画面の部分はサーバー描画しない」が正確です。公開ページはNext.jsでサーバー描画し、/admin配下だけReact-adminにする構成は普通に組めます。
React-adminとRefine・AdminJS・Retoolの選び分け
管理画面を作る手段はReact-adminだけではありません。よく比べられる3つと、違いが出る点だけを並べます。
| 観点 | React-admin | Refine | AdminJS | Retool |
|---|---|---|---|---|
| 書き方 | Reactのコンポーネント | フック中心(ヘッドレス) | Node.jsのリソース設定 | 画面をGUIで配置 |
| つなぐ先 | 任意のAPI | 任意のAPI | ORM経由でDB | DBやAPIへ直結 |
| 標準UI | MUI(shadcn版あり) | Ant Design・MUIなど選択 | 独自デザイン | 独自部品 |
| 費用 | MIT。一部モジュールは有償 | MIT。一部有償 | MIT | 利用者数で課金 |
APIが既にあり、画面はReactで細かく作り込みたいならReact-adminです。UIライブラリを自分で決めたい、デザインシステムが既にあるならRefineが合います。両者の違いはRefine(React)とは?react-adminとの違い・v5の使い方と管理画面の作り方で掘り下げています。APIを作らずにNode.jsのORMから直接画面を出すならAdminJS(AdminJSとは?Node.jsの管理画面を自動生成する使い方とPrisma 7・Express 5の注意点【7.8.17】)、コードを書かずに社内ツールを並べるならRetool(Retoolとは?社内管理画面を短期間で作る構成とDB直結の権限設計、内製の限界)が候補です。バックエンドがDjangoなら、標準のadminで足りるかを先に確かめたほうが早く、その線引きはDjango管理画面の設計:admin標準の範囲とModelAdmin・権限の実装にまとめています。
料金:MITの無償版とEnterprise Editionの3プラン
react-admin本体とra-core、既製のdataProviderはMITライセンスで、商用でも無料です。ここまでに書いた一覧・編集・検索・ログイン・canAccessによる画面単位の権限は、すべて無償版で動きます。
有償のEnterprise Editionは、プライベートnpmレジストリから追加モジュールを入れる形のサブスクリプションです。Enterprise Editionの料金ページ(2026年10月28日確認)の表示は次のとおりで、価格はいずれも年払いの月額換算です。
| プラン | 月額換算 | 開発者数 |
|---|---|---|
| Team | 145ユーロ | 2人まで |
| Business | 290ユーロ | 10人まで |
| Corporate | 590ユーロから | 無制限 |
どのプランもプロジェクト数の制限はありません。追加モジュールには、ロール・グループ単位の権限を扱うra-rbac、リアルタイム更新のra-realtime、操作履歴のra-audit-log、ra-calendar・ra-tree・ra-editable-datagridなどがあります(Ecosystemのページ)。判断は、要件に必要なモジュールを並べ、それぞれを無償版の上に自作する工数と年額を比べて行います。権限をロール定義ごと管理したい、複数人の同時編集をリアルタイムに反映したい、操作履歴を残したいといった要件が複数重なるほど、有償版のほうが安く済みやすくなります。価格は改定されることがあるので、契約前に料金ページで確かめてください。
React-adminを採用すべきでない場面
React-adminが速いのは、「APIの上にCRUD画面を並べる」という型に収まる間だけです。次の条件に当てはまるなら、別の手段を先に検討してください。
- 検索流入を狙う公開ページ:管理画面はクライアント描画で、サーバー描画できません。公開サイトはNext.jsなどで作り、React-adminは
/admin配下に閉じます。 - 画面がCRUDの型に収まらない:ドラッグで並べ替える工程表や、1画面で複数リソースを同時に編集する業務画面では、標準部品で省ける実装より独自に書く部分のほうが多くなりがちです。データ取得や認証の層は再利用できますが、画面の大半を自作するならReact-adminを入れる理由は薄れます。
- 初回の読み込みを小さく保ちたい:本記事の2リソースのサンプルをVite 8.3.5でビルドすると、Viteのビルドログで、JavaScriptは1チャンクの1,185.85kB(gzip後382.98kB)でした。MUIの部品とReact-adminが同じチャンクにまとまるためで、社外の取引先が回線の細い環境で開く画面なら、コード分割を前提にします。
- APIが無く、作る予定もない:React-adminはAPIの存在が前提です。DBから直接画面を出したいならAdminJSやRetoolのほうが早く立ち上がります。
逆に、社内向けの受発注・在庫・会員管理のように、APIが整っていて画面数が多い業務システムでは、規約に沿うだけで画面が揃っていくのが大きな強みです。基幹業務の画面をReact-adminのような構成で内製するか外部に頼むかで迷う場合は、基幹システム開発の支援内容も参考にしてください。
よくある質問
React-adminの最新バージョンは?
2026年10月28日時点のnpmの最新は5.15.5(2026年10月19日公開)です。5.15.0(2026年6月24日)でMUI v9に対応しました。リリースは頻繁なので、npm view react-admin versionか公式のリリースノートで確かめてください。
React-adminは無料で使えますか?
本体はMITライセンスで、商用でも無料です。権限制御のcanAccessも5.3.0から無償版に含まれます。ロール定義を扱うRBACモジュールやリアルタイム更新は有償のEnterprise Editionで、年払いの月額換算145ユーロ(開発者2人まで)からです。
dataProviderとは何ですか?
画面とAPIのあいだの変換層で、getListやupdateなど9つのメソッドを持つオブジェクトです。ra-data-simple-restなどの既製品を使うか、APIの形式に合わせて自作します。本記事で比べたREST用の2つは総件数をレスポンスヘッダーから読みます。総件数を返せないAPIなら、totalの代わりにpageInfoを返す方法もあります。
API PlatformとReact-adminを組み合わせるには?
@api-platform/adminのHydraAdmin(OpenAPIならOpenApiAdmin)にAPIのエントリポイントを渡します。Symfony版のディストリビューションには最初から入っていて、/adminで開けます。表示されないときはCORSの許可オリジンとLinkヘッダーの公開を確認してください。
React-adminはNext.jsで使えますか?
使えます。管理画面を"use client"のコンポーネントにし、next/dynamicのssr: falseで読み込むのが公式の手順です。管理画面の部分はサーバー描画されません。