生成 AI として今年はブレイクしている ChatGPT は JavaScript や TypeScript のサンプルを紹介してくれます。今回は ChatGPT が生成するコードを利用して、XM Cloud のコンポーネントを作成したいと思います。
![](/_next/image?url=https%3A%2F%2Fimages.ctfassets.net%2Fzi1ovlormku8%2F6S3YDD1rK0vMirteC01SKs%2Fdae3a15f29d9b2413c5585c5221982e0%2Fmohamed-nohassi-tdu54W07_gw-unsplash.jpg&w=3840&q=75)
YouTube のコンポーネントを作成する
まず最初に、YouTube のためのコンポーネントを作成しますが、まずはシンプルなコンポーネントを作成してください。手順は、別の記事でウィザードを使う手順を紹介しています。
今回は、コンポーネント名は YouTube として作成し、アイコンでは Multimedia/32x32/video_camera.png を利用しました。アイコンとしては以下のように表示されています。
![xmcchatgpt01.png](/_next/image?url=https%3A%2F%2Fimages.ctfassets.net%2Fzi1ovlormku8%2F1SitYHCZqLXNNk1MX81MYs%2F44c00e198360f340d135633210c4ce1d%2Fxmcchatgpt01.png&w=1920&q=75)
ChatGPT にご相談
早速ですが、ChatGPT にコードの相談をしてみます。
YouTube の動画を埋め込む typescript のコンポーネントのサンプルの書き方
以下のようにコードと合わせて回答をしてくれます。
![xmcchatgpt01.png](/_next/image?url=https%3A%2F%2Fimages.ctfassets.net%2Fzi1ovlormku8%2FSdN6eUtM2EusC8ZChOS8V%2F31caa3fd3bbba26f191d5eb2d42bb200%2Fxmcchatgpt01.png&w=1920&q=75)
実際に提供されたコードは今回は以下の通りです。
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つの項目となります。そこで、事前に用意しているコンポーネントのテンプレートの項目を変更します。
![xmcchatgpt03.png](/_next/image?url=https%3A%2F%2Fimages.ctfassets.net%2Fzi1ovlormku8%2F2CTorZNn6Byi5Troow0v5T%2F447a996134200513690cec45758a4a78%2Fxmcchatgpt03.png&w=3840&q=75)
また Standard Value に、今回はサイズをデフォルトで設定するようにします。
![xmcchatgpt04.png](/_next/image?url=https%3A%2F%2Fimages.ctfassets.net%2Fzi1ovlormku8%2FWnmblu3xNHBZ54zsi0P0b%2Fdd48379234959d17313477e1fd4e30c8%2Fxmcchatgpt04.png&w=3840&q=75)
これに合わせて、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 のアイテムが完成しています。
![xmcchatgpt06.png](/_next/image?url=https%3A%2F%2Fimages.ctfassets.net%2Fzi1ovlormku8%2F2eFJHJAf1q1ACVCsN8ccvY%2F9da8fa9121f5b144c6a578567da5d59c%2Fxmcchatgpt06.png&w=3840&q=75)
コードをマージする
今回はちょっと乱暴に、YouTube.tsx のファイルに対して ChatGPT が提供しているコードをそのままコピペをします。
![xmcchatgpt07.png](/_next/image?url=https%3A%2F%2Fimages.ctfassets.net%2Fzi1ovlormku8%2F7yMzssNnEPrcjrpAma0eSL%2F9c8c30682e33a53b488f6a9f5bf2b0d0%2Fxmcchatgpt07.png&w=1920&q=75)
以下の部分を変更しました。
- 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 の値を参照できるようにしました。
動作確認とデバッグ
実際に事前に作成したコンポーネントを配置しているページを見ると以下のようになっています。
![xmcchatgpt08.png](/_next/image?url=https%3A%2F%2Fimages.ctfassets.net%2Fzi1ovlormku8%2F3aafDxsKOOXYTscMmjCwbt%2Fa07a814dfaf3550b47fc54658c882d3c%2Fxmcchatgpt08.png&w=3840&q=75)
YouTube の動画が2つ並んでいます。このデバッグも ChatGPT に聞いてみましょう。
![xmcchatgpt09.png](/_next/image?url=https%3A%2F%2Fimages.ctfassets.net%2Fzi1ovlormku8%2F4qPZ6zmeoIbyuVV3q0NoLD%2Fae97609d31dac82dc1224e60eed6d149%2Fxmcchatgpt09.png&w=3840&q=75)
回答が返ってきました。
![xmcchatgpt10.png](/_next/image?url=https%3A%2F%2Fimages.ctfassets.net%2Fzi1ovlormku8%2F38gRudtgC42LOTM7KU5BGB%2F5bafcd21d93ed0ef471ddedf37c47d02%2Fxmcchatgpt10.png&w=3840&q=75)
コードの違いは画面に出ているコメント部分です。実際にこれを反映させたあと、コンポーネントを表示すると以下のようになります。
![xmcchatgpt11.png](/_next/image?url=https%3A%2F%2Fimages.ctfassets.net%2Fzi1ovlormku8%2F5RommEDrYjqloMRx3ADxVl%2F345a5d19242dff07c8c63ee8796e517a%2Fxmcchatgpt11.png&w=3840&q=75)
無事、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 で管理することができるコンポーネントを作れるようになったとは、いい時代になったものです。