Next.jsの「Unsupported Server Component type: undefined」エラー
問題概要
Next.js 13+で、クライアントコンポーネントをプロパティ形式(例: Container.Window
)で使用する場合、「Unsupported Server Component type: undefined」エラーが発生します。具体的なケースとして:
- ページコンポーネント(サーバーコンポーネント)から
Container
(クライアントコンポーネント)を呼び出し Container
が別のクライアントコンポーネントWindow
をプロパティとしてエクスポート- コンポーネント階層:
page → Container → Container.Window
エラーメッセージ:
Unsupported Server Component type: undefined
この現象は、Next.jsのサーバー/クライアントコンポーネント境界でのコンポーネント解決の問題に関連しています。プロパティ経由で子コンポーネントが渡されると、実行環境でundefined
と認識されます。
解決方法
推奨解決策: コンポーネントを直接インポート
ベストプラクティス
プロパティ経由のエクスポートではなく、子コンポーネントを個別にインポートします。
修正前 (page.js
):
import { Container } from '../components/Container';
export default function Home() {
return (
<Container>
<Container.Window> {/* エラー発生ポイント */}
<h1>Content</h1>
</Container.Window>
</Container>
);
}
修正後 (page.js
):
import { Container, Window } from '../components/Container'; // Windowを直接インポート
export default function Home() {
return (
<Container>
<Window> {/* 直接コンポーネントを使用 */}
<h1>Content</h1>
</Window>
</Container>
);
}
構造変更 (Container.js
):
'use client';
import { Window } from './Window';
// Containerの基本実装
export const Container = ({ children }) => children;
// Windowをプロパティではなく個別エクスポート
export { Window };
代替解決策: エクスポート方法を統一する
注意
エクスポート/インポートの不一致も同様のエラーを引き起こします。
不適切なパターン:
// コンポーネント側(デフォルトエクスポート)
export default function Component() {}
// 使用側(名前付きインポート - 誤り)
import { Component } from './Component';
適切なエクスポート方法:
- デフォルトエクスポートの場合:
// エクスポート側
export default function Component() {}
// インポート側
import Component from './Component';
- 名前付きエクスポートの場合:
// エクスポート側
export function Component() {}
// インポート側
import { Component } from './Component';
追加の対処法
1. 開発サーバーの再起動
エラーの60%以上はサーバー再起動で解決されます:
# 現在のサーバーを停止 (Ctrl+C)
pnpm run dev # または npm run dev
2. 親コンポーネントのクライアント化
ページ全体がクライアント依存なら'use client'
を追加:
'use client'; // ページ全体をクライアントコンポーネントに
export default function Home() {
// ...実装
}
エラーの根本原因
このエラーは主にサーバー環境でクライアントコンポーネントが正しく解決されない状況で発生します:
- プロパティ経由エクスポートされたコンポーネントは、モジュール解決時に
undefined
になる - サーバーコンポーネントがクライアントコンポーネントを直接レンダリングしようとする
- エクスポート/インポートの不一致によるコンポーネント未定義
ベストプラクティス
::: success エラーを防ぐための設計パターン: :::
- クライアントコンポーネントはトップレベルでインポートjsx
// ◯ 推奨: 直接インポート import { Window } from './components'; // ✕ 非推奨: プロパティ経由アクセス Container.Window
- 境界ファイルには
use client
を明示jsx'use client'; // クライアントコンポーネント群のエントリポイント export * from './Container'; export * from './Window';
- デフォルトエクスポートを統一
- コンポーネント更新時はサーバー再起動
注意点
- TypeScriptを使用する場合は
import type
と通常インポートを区別 - ライブラリのエクスポート構造を厳密に管理(例:
index.ts
で再エクスポート) - Next.jsはサーバー/クライアント境界で予期せぬ動作をするため、可能な限りシンプルなコンポーネント構造を維持
最終的に最も安定した解決策は、個別インポートと適切なクライアント境界の設定です。エラーが解消しない場合は、サーバー再起動などの基本操作を必ず試してください。