Nuxt Nation カンファレンスが開催されます。11月12日〜13日にご参加ください。

nuxt-ssr-lit

Lit Elementコンポーネントのサーバーサイドレンダリング

nuxt-ssr-lit

Litカスタム要素のサーバーサイドレンダリングとクライアントサイドハイドレーションを行うためのNuxt3モジュールです。

🚀 使い方

注意: このモジュールはNuxt3用です。 Nuxt2のサポートについては、こちらのIssueをご覧ください。モジュールの完成に協力してくれる方を募集しています。

インストール

nuxt-ssr-litをインストールします。

npx nuxi@latest module add ssr-lit

nuxt.config.jsのmodulesセクションに以下のコードを追加します。

import { defineNuxtConfig } from "nuxt";

export default defineNuxtConfig({
  modules: [
    ["nuxt-ssr-lit", { litElementPrefix: ["acme-"] }]
    // ...
  ]
});

これで完了です! acme- で始まるすべてのLit要素はサーバーサイドレンダリングされます。プロジェクトに他のカスタム要素がある場合、それらはクライアントサイドレンダリングされます。

👨‍💻 開発

  • 型スタブを生成するには、npm run dev:prepareを実行します。
  • playgroundを開発モードで起動するには、npm run devを使用します。

よくある問題

TypeError: customElements.get(...) is not a constructor

このエラーは、Lit要素が正しく登録されていない場合に発生します。これは、要素が正しく設定されていないか、要素に副作用があることが原因で発生する可能性があります。また、本番モードで実行している場合にのみ、このエラーが表示される場合があります。

これを修正するには、カスタム要素ライブラリをnuxt.config.jsファイルに登録します。

export default defineNuxtConfig({
  ...
  nitro: {
    moduleSideEffects: ["my-custom-element-library"]
  }
});

仕組み

モジュールオプションで指定されたプレフィックスを使用するNuxtプロジェクトのすべてのLit要素は、LitWrapperと呼ばれるVueコンポーネントでラップされます。

この自動ラッピングは、AutoLitWrapperと呼ばれるViteプラグインを介して行われるため、ビルド時に行われます。デフォルトでは、プラグインはVueファイルに対してのみ動作するため、不要な処理を回避することでパフォーマンスを最適化できます。

そのため、いずれかのコンポーネントで使用されているLit要素がある場合、例えば <acme-button>Hello world</acme-button> の場合、実際に生成されNuxt/Vueで使用されるコードは <LitWrapper><acme-button>Hello world</acme-button></LitWrapper> になります。

サーバーサイドのLitWrapperコンポーネントは、@lit-labs/ssrLitElementRendererを使用して、ラップされたLit要素をDeclarative Shadow DOMでレンダリングします。これにより、JSを読み込んで実行することなく、サーバーHTMLが解析されるとすぐに、Litコンポーネントがブラウザに正しくレンダリングされます。

クライアントサイドのLitWrapperコンポーネントは何もしないで、通常のクライアントサイドハイドレーションを実行させます。

注意点

Litコンポーネントは、小さなDOMシムをNodeに適用することで、Node側でSSRされます。すべてのDOM APIが利用できるわけではありません。例えば、割り当てられたスロットまたは子を取得する、カスタムイベントをディスパッチする、サーバーサイドで呼び出されるライフサイクルフックにイベントリスナーを追加するなどは動作しません。サーバーで実行されるコードでこのようなクライアントサイドのアクティビティを避けることが重要です。

また、詳細は@lit-labs/ssrライブラリステータスをご確認ください。