0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.jsのサーバーコンポーネントでrenderToStaticMarkupを使用する方法

Posted at

はじめに

Next.jsのApp Routerでサーバーコンポーネントを使用している際に、Reactコンポーネントを静的なHTML文字列に変換したいケースがあります。

例えば、動的な文書生成やメール本文の作成などの用途です。

renderToStaticMarkupとは

renderToStaticMarkupは、React DOMのreact-dom/serverモジュールが提供する関数で、Reactコンポーネントを純粋なHTML文字列に変換します。

通常のReactレンダリングで生成されるDOM属性(data-reactrootなど)を含まない、軽量なHTMLを生成するために使用されます。

renderToStringとの違いは、renderToStaticMarkupがReact固有の属性を含まないため、サイズが小さく、クライアントでのハイドレーションが不要な場合に適しています。

問題: サーバーコンポーネントでの直接インポートはエラーになる

サーバーコンポーネントでは、react-dom/serverモジュールを直接インポートすることができません。

例えば、以下のようなコードはエラーになります。

// ❌ これはエラーになる
import { renderToStaticMarkup } from 'react-dom/server';

export default function MyServerComponent() {
  const html = renderToStaticMarkup(<div>Hello World</div>);
  return <div>{html}</div>;
}

実行すると、次のようなエラーが表示されます。

Error: You're importing a component that imports react-dom/server. To fix it, render or return the content directly as a Server Component instead for perf and security.
Learn more: https://nextjs.org/docs/app/building-your-application/rendering

react-dom/serverをインポートするコンポーネントをインポートしています。これを修正するには、パフォーマンスとセキュリティのために、コンテンツを直接Server Componentとしてレンダリングまたは返すようにしてください。詳細はこちら:https://nextjs.org/docs/app/building-your-application/rendering

解決策: 動的インポートを使用する

この問題を解決するために、動的インポートを使用する方法があります。

// test-render.tsx
export const renderToHTML = async (): Promise<string> => {
  const ReactDOMServer = await import("react-dom/server");
  const html = ReactDOMServer.renderToStaticMarkup(<button>hello</button>);
  return html;
};

この動的インポートを使用した関数は、Next.jsのServer ActionsやAPIルートなど、サーバーサイドで実行される様々な場所から呼び出すことができます。

解説

この解決策が機能する理由は以下のとおりです。

  • サーバーコンポーネントの制約: Next.jsのサーバーコンポーネントでは特定のモジュール(この場合はreact-dom/server)に直接アクセスできない制限があるようです。
  • 動的インポート: await import()を使うことで、実行時にモジュールをロードでき、静的な依存関係チェックを回避できます。

注意点

  • この方法はサーバーサイドでのみ動作します(ブラウザでは動作しません)
  • 実行時のパフォーマンスを考慮する必要があります(動的インポートにはオーバーヘッドがあります)
  • Next.jsのバージョンアップによって動作が変わる可能性があるため、最新の公式ドキュメントも参照してください

まとめ

Next.jsのサーバーコンポーネントでrenderToStaticMarkupを使用したい場合は、動的インポートを使用することで実現できます。この方法を使うことで、Reactコンポーネントをサーバーサイドで静的なHTMLに変換し、さまざまな用途に活用することができます。

参考

Unable to import react-dom/server in a server component #43810

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?