ChatGPT が生成したコードを参考にコンポーネントを作成する

公開日 :

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

YouTube のコンポーネントを作成する

まず最初に、YouTube のためのコンポーネントを作成しますが、まずはシンプルなコンポーネントを作成してください。手順は、別の記事でウィザードを使う手順を紹介しています。

今回は、コンポーネント名は YouTube として作成し、アイコンでは Multimedia/32x32/video_camera.png を利用しました。アイコンとしては以下のように表示されています。

random desc

ChatGPT にご相談

早速ですが、ChatGPT にコードの相談をしてみます。

YouTube の動画を埋め込む typescript のコンポーネントのサンプルの書き方

以下のようにコードと合わせて回答をしてくれます。

random desc

実際に提供されたコードは今回は以下の通りです。

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つの項目となります。そこで、事前に用意しているコンポーネントのテンプレートの項目を変更します。

random desc

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

random desc

これに合わせて、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 のアイテムが完成しています。

random desc

コードをマージする

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

random desc

以下の部分を変更しました。

  • 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 の値を参照できるようにしました。

動作確認とデバッグ

実際に事前に作成したコンポーネントを配置しているページを見ると以下のようになっています。

random desc

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

random desc

回答が返ってきました。

random desc

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

random desc

無事、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 で管理することができるコンポーネントを作れるようになったとは、いい時代になったものです。