生成 AI として今年はブレイクしている ChatGPT は JavaScript や TypeScript のサンプルを紹介してくれます。今回は ChatGPT が生成するコードを利用して、XM Cloud のコンポーネントを作成したいと思います。

YouTube のコンポーネントを作成する
まず最初に、YouTube のためのコンポーネントを作成しますが、まずはシンプルなコンポーネントを作成してください。手順は、別の記事でウィザードを使う手順を紹介しています。
今回は、コンポーネント名は YouTube として作成し、アイコンでは Multimedia/32x32/video_camera.png を利用しました。アイコンとしては以下のように表示されています。

ChatGPT にご相談
早速ですが、ChatGPT にコードの相談をしてみます。
YouTube の動画を埋め込む typescript のコンポーネントのサンプルの書き方
以下のようにコードと合わせて回答をしてくれます。

実際に提供されたコードは今回は以下の通りです。
import React, { useRef, useEffect } from 'react';
interface YouTubeEmbedProps {
videoId: string;
width?: number;
height?: number;
}
const YouTubeEmbed: React.FC<YouTubeEmbedProps> = ({ videoId, width = 560, height = 315 }) => {
const playerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (playerRef.current) {
const iframe = document.createElement('iframe');
iframe.src = `https://www.youtube.com/embed/${videoId}`;
iframe.width = width.toString();
iframe.height = height.toString();
iframe.frameBorder = '0';
iframe.allowFullscreen = true;
playerRef.current.appendChild(iframe);
}
}, [videoId, width, height]);
return (
<div ref={playerRef}></div>
);
};
export default YouTubeEmbed;
このコードを参考に、Headless SXA のコンポーネントを作成していきましょう。
アイテムフィールドの定義
上記のコードのうち、コンポーネントが利用するプロパティに関しては、videoId、widthおよび height の3つの項目となります。そこで、事前に用意しているコンポーネントのテンプレートの項目を変更します。

また Standard Value に、今回はサイズをデフォルトで設定するようにします。

これに合わせて、YouTube.tsx のファイルは以下のように変更しました。
import React from 'react';
import { Field, Text } from '@sitecore-jss/sitecore-jss-nextjs';
interface Fields {
videoId: Field<string>;
width: Field<string>;
height: Field<string>;
}
type YouTubeProps = {
params: { [key: string]: string };
fields: Fields;
};
export const Default = (props: YouTubeProps): JSX.Element => {
return (
<div className={`component myrendering ${props.params.styles}`}>
<div className="component-content">
<div>
<strong>テスト:</strong>
<Text field={props.fields.videoId} />
<div>width={props.fields.width.value}</div>
<div>height={props.fields.height.value}</div>
</div>
</div>
</div>
);
};
実際にこのコンポーネントをページに配置してみると、以下のようになります。今回は、YouTube の ID を入力して保存しておきます。この結果、ホームに紐づいたアイテムとして、YouTube のアイテムが完成しています。

コードをマージする
今回はちょっと乱暴に、YouTube.tsx のファイルに対して ChatGPT が提供しているコードをそのままコピペをします。

以下の部分を変更しました。
- import のところで重複ができているため、ChatGPT が記載している1行を先頭に記載
- interface の部分も上に移動
- YouTubeEmbedProps の定義で width? と height? という記載をしていましたが、必ず値を渡す形にしたいので ? を削除
- 合わせて、Sitecore から受け取るデータはテキストとして利用するため、今回は number を string に変更します。
結果、まずは以下のようなコードになりました。
import React, { useRef, useEffect } from 'react';
import { Field, Text } from '@sitecore-jss/sitecore-jss-nextjs';
interface Fields {
videoId: Field<string>;
width: Field<string>;
height: Field<string>;
}
interface YouTubeEmbedProps {
videoId: string;
width: string;
height: string;
}
type YouTubeProps = {
params: { [key: string]: string };
fields: Fields;
};
続いて、ChatGPT から取得した YouTube の表示をする部分を関数として書き換えます。変更点としては、
- width と height で標準の値として設定していた部分を削除
- Visual Studio Code が iframe.frameBorder に関して警告を出していたため削除します。
- width と height に関しては Sitecore からは文字列として取得するため、.toString() を削除。
結果以下のようになります。
function YouTubeEmbed({ videoId, width, height }: YouTubeEmbedProps) {
const playerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (playerRef.current) {
const iframe = document.createElement('iframe');
iframe.src = `https://www.youtube.com/embed/${videoId}`;
iframe.width = width;
iframe.height = height;
iframe.allowFullscreen = true;
playerRef.current.appendChild(iframe);
}
}, [videoId, width, height]);
return <div ref={playerRef}></div>;
}
この関数を、Default が呼び出すように設定をします。呼び出しはシンプルに、以下のコードになります。
export const Default = (props: YouTubeProps): JSX.Element => {
return (
<div className={`component myrendering ${props.params.styles}`}>
<div className="component-content">
<div>
<YouTubeEmbed
videoId={props.fields.videoId.value}
width={props.fields.width.value}
height={props.fields.height.value}
/>
</div>
</div>
</div>
);
};
これで ChatGPT が生成したコードを関数として組み込み、Sitecore の値を参照できるようにしました。
動作確認とデバッグ
実際に事前に作成したコンポーネントを配置しているページを見ると以下のようになっています。

YouTube の動画が2つ並んでいます。このデバッグも ChatGPT に聞いてみましょう。

回答が返ってきました。

コードの違いは画面に出ているコメント部分です。実際にこれを反映させたあと、コンポーネントを表示すると以下のようになります。

無事、YouTube の動画を埋め込むコンポーネントが動きました。
最後にコードを整理していきます。今回、マージしたり使わなくなった import が残っているためです。
import React, { useRef, useEffect } from 'react';
import { Field } from '@sitecore-jss/sitecore-jss-nextjs';
これで build も通り、コンポーネントが無事完成しました。
まとめ
前回、コンポーネントの作成に関して、ウィザードで作成する方法を紹介しました。その際はテキストのフィールドのみで定義をしていました。今回は YouTube の動画を表示するためのコードを用意するために、ChatGPT を利用してサンプルを作成しました。また、そのサンプル自体は2つ動画を表示してしまうことになりましたが、それを1つにする方法も ChatGPT を利用してデバッグすることができました。
Typescript に関して、間違いなく ChatGPT は達人です。こんな感じで、Sitecore で管理することができるコンポーネントを作れるようになったとは、いい時代になったものです。