画像付きプロフィールカードを作ろう【HubSpot × React DAY7】

目次
はじめに 🌿
社員紹介ページやチームメンバー紹介など、「写真+名前+ひとこと紹介」をまとめて表示したいときってあるよね。
そんなときに活躍するのが、画像付きプロフィールカード!
今回は、HubSpot CMS × React を使って、ページ編集画面から画像・名前・紹介文を自由に入力できるプロフィールカードを作っていきます🐱💻
この記事でわかること ✏️
-
HubSpotの
ImageField
を使った画像フィールドの作り方 -
CMS編集画面で画像・テキストを編集できるモジュール構成
-
RepeatedFieldGroup
を使って複数人表示する方法 -
dangerouslySetInnerHTML
の意味と使いどころ
結論 🎯
ImageField
と RichTextField
を組み合わせれば、
社員紹介カードが簡単に作れる!
さらに RepeatedFieldGroup
を使えば複数人対応もできちゃう✨
Step1:1人分のプロフィールカードを作ろう 🧸
まずは基本の1人分プロフィールカードを作ってみよう!
画像・名前・役職・紹介文をセットで表示していくよ。
👇 まずは完成イメージの動作はこちら
サンプルコード(1人表示)
// フィールドの読み込み
import {
ModuleFields,
TextField,
ImageField,
RichTextField,
} from '@hubspot/cms-components/fields';
// デフォルト画像の読み込み
import image from '../../../assets/charo.png';
// fieldValues の宣言
export function Component({ fieldValues }) {
const { src, alt, width, height } = fieldValues.image;
// 実際にページに返される情報
return (
<div
style={{
backgroundColor: '#faf0e6',
borderRadius: '12px',
padding: '24px',
maxWidth: '400px',
textAlign: 'center',
margin: '0 auto',
boxShadow: '0 4px 12px rgba(0,0,0,0.1)',
}}
>
<img
src={src}
alt={alt}
width={width}
height={height}
style={{ borderRadius: '50%', marginBottom: '16px' }}
/>
<h2>{fieldValues.name_hi}</h2>
<div style={{ fontStyle: 'italic', color: '#666' }}>
<span>{fieldValues.position}</span>
</div>
<div
style={{ marginTop: '12px', fontSize: '14px', color: '#333' }}
dangerouslySetInnerHTML={{ __html: fieldValues.bio }}
// HTML文字列を表示させるための書き方
/>
</div>
);
}
// フィールドの設定
export const fields = (
<ModuleFields>
<ImageField
name="image"
label="プロフィール画像"
default={{ src: image, height: 100, alt: 'プロフィール画像' }}
resizable={true}
/>
<TextField
name="name_hi"
label="名前"
default="サンプル ちゃろ"
/>
<TextField
name="position"
label="役職"
default="フロントエンドエンジニア"
/>
<RichTextField
name="bio"
label="紹介文"
default="<p>Reactと猫が好きなエンジニアです。</p>"
/>
</ModuleFields>
);
// モジュールのメタ情報
export const meta = {
label: '07_プロファイルカード',
};
Step2:複数人のプロフィールを繰り返し表示しよう 🐾
応用編として、今度はチーム紹介のように複数人分のカードを表示してみましょう。
Reactでのループ処理とCMSフィールドを組み合わせるだけで、かなり柔軟に使えるモジュールに!
👇 複数表示のモジュールの動きはこんな感じ
サンプルコード(繰り返し対応)
import {
ModuleFields,
TextField,
ImageField,
RichTextField,
RepeatedFieldGroup,
// 追加で繰り返しフィールドを読み込む
} from '@hubspot/cms-components/fields';
import image from '../../../assets/charo.png';
export function Component({ fieldValues }) {
const { cards } = fieldValues;
return (
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '20px', justifyContent: 'center' }}>
{cards?.map((card, index) => {
// map () を使って配列から表示させる
const { image, name_hi, position, bio } = card;
return (
<div
key={index}
style={{
backgroundColor: '#faf0e6',
borderRadius: '12px',
padding: '24px',
maxWidth: '300px',
textAlign: 'center',
boxShadow: '0 4px 12px rgba(0,0,0,0.1)',
}}
>
<img
src={image.src}
alt={image.alt}
width={image.width}
height={image.height}
style={{ borderRadius: '50%', marginBottom: '16px' }}
/>
<h2>{name_hi}</h2>
<div style={{ fontStyle: 'italic', color: '#666' }}>{position}</div>
<div
style={{ marginTop: '12px', fontSize: '14px', color: '#333' }}
dangerouslySetInnerHTML={{ __html: bio }}
/>
</div>
);
})}
</div>
);
}
// RepeatedFieldGroupを追加
export const fields = (
<ModuleFields>
<RepeatedFieldGroup
name="cards"
label="カード一覧"
occurrence={{ min: 1, max: 10, default: 1 }}
default={[
{
image: { src: image, alt: 'プロフィール画像', height: 100 },
name_hi: 'サンプルちゃろ',
position: 'フロントエンドエンジニア',
bio: '<p>Reactと猫が好きなエンジニアです。</p>',
},
]}
>
<ImageField
name="image"
label="プロフィール画像"
default={{ src: image, height: 100, alt: 'プロフィール画像' }}
resizable={true}
/>
<TextField name="name_hi" label="名前" default="サンプルちゃろ" />
<TextField name="position" label="役職" default="フロントエンドエンジニア" />
<RichTextField
name="bio"
label="紹介文"
default="<p>Reactと猫が好きなエンジニアです。</p>"
/>
</RepeatedFieldGroup>
</ModuleFields>
);
export const meta = {
label: '07_プロファイルカード(複数対応)',
};
繰り返しフィールド、map の書き方については以下記事を参考にしてね:
フィールド名の注意点
RepeatedFieldGroup
を使うときは、フィールドの name
と default のキー名を完全に一致させる必要があるよ!
たとえば name="name_hi"
にしているなら、default の中も name_hi
にしておかないと、初期値が反映されないので注意👀
🧠 dangerouslySetInnerHTML
って何?
dangerouslySetInnerHTML
は、HTMLタグつきの文字列(たとえば <p>〜</p>
)をReactでそのまま表示したいときに使う特別な書き方になります。
なんで必要なの?
Reactは <p>こんにちは</p>
のようなHTMLタグを含む文字列を、普通の文字列として表示しちゃうんだよね。
だから、これはHTMLとして描画してね!ってわざわざ指示してあげないといけない。
<div dangerouslySetInnerHTML= />
これを使うと、CMSから入力された <p>
や <strong>
などのタグがちゃんと適用されて表示されるようになるの。
「dangerously」がついている理由
名前がちょっと怖いのは、セキュリティ上の理由から。
たとえば悪意のある <script>
タグなんかが混ざってたら危険ですよね(・。・;
だからReactは「これほんとに描画して大丈夫?危なくない?」ってあえて警告っぽくしてあるようです。
でもHubSpotの RichTextField
は、CMS側でちゃんと安全に処理してくれるから、基本的には安心して使ってOK(のはず)!
まとめ ✨
Reactモジュールでも、ImageField
と RichTextField
を使えば、
CMSで編集しやすくて見た目もかわいいプロフィールカードが作れちゃう!
RepeatedFieldGroup
を使って繰り返しフィールドを追加すれば、チーム紹介や社員紹介ページにもばっちり対応できるよ!
💬 コメントしてみる?