😎
【Inertia.js】[object Object] could not be cloned.の対処法
背景
Laravel + Inertia.js + Vue3でSPA開発を行なっていました。
そして、チャネルトークのSPA用スクリプト導入を行なったところエラー発生しました。
実装
チャネルトークの起動には、PluginKeyが必須です。
shareInertiaData.phpからusePage関数経由でPluginKeyを取得して使用していました。
shareInertiaData.php
public function handle(Request $request, callable $next)
{
Inertia::share(['channelTalk' => [
'pluginKey' => 'my-plugin-key',
]]);
return $next($request);
}
channel-talk.js
const page = usePage();
if (page.props.value.channelTalk) {
// チャネルトーク起動
ChannelService.boot(page.props.value.channelTalk);
}
エラー
usePage関数から取得したPluginKeyをそのままChannelService.boot
関数の引数に渡すと以下のエラーが発生しました。
Uncaught DOMException: Failed to execute 'structuredClone' on 'Window': [object Object] could not be cloned.
原因
inertia.jsのusePage()関数から取得できるProxyオブジェクトをそのまま使っていたのが原因でした。
inertia.jsのリポジトリにも似たような現象が報告されていた。
解決策
JSON.parse関数とJSON.stringify関数を使い、Proxyオブジェクトを変換する。
例
JSON.parse(JSON.stringify(usePage().props));
下記のように実装を修正すれば、私のエラーも無事消えました。
channel-talk.js
const page = usePage();
if (page.props.value.channelTalk) {
// チャネルトーク起動
- ChannelService.boot(page.props.value.channelTalk);
+ ChannelService.boot(JSON.parse(JSON.stringify(page.props.value.channelTalk)));
}
Discussion