リッチテキスト・マークダウン内の画像にalt・width・heightを設定する

最終更新日:

Table of contents

概要

リッチテキストフィールド・マークダウンフィールドを利用して画像を埋め込んだ場合、返却されるHTMLデータ内のimg要素には、alt・width・heightなどの属性が入力されていません。
※ マークダウンフィールドの場合は、alt属性を設定可能です。

そこでこの記事では、以下の2つのやり方で、img要素にalt・width・height属性を追加する方法を紹介します。

  • マルチタイプフィールドを使う方法
  • コンテンツに画像フィールドを追加し、リッチテキストのimg要素から画像の情報を取得可能にする方法

メディアライブラリでのメタ情報の設定について

まず、どちらの方法でも利用することとなる、メディアライブラリでのメタ情報の設定について説明します。

「メディアライブラリ」より画像を選択すると、タイトル、代替テキスト、説明などのメタ情報を入力できます。メタ情報には、独自のプロパティを追加・入力することも可能です。

set-attributes1.jpg

ここでは、1つ画像を選択し、alt属性に使用したい値を「代替テキスト」に入力し、「変更を保存」をクリックします。

set-attributes2.jpg

これで、画像フィールドを利用した場合、以下のようなオブジェクトとして取得できます。
altText に設定した値が入力されていることがわかります。

{
  "_id": "667cd3fec034b1bff6b2aa6d",
  "altText": "hogehoge",
  "description": "",
  "fileName": "newt.webp",
  "fileSize": 142662,
  "fileType": "image/webp",
  "height": 1400,
  "metadata": {},
  "src": "https://xxxxxx.assets.newt.so/v1/0971bfec-df41-4ef2-86ab-096dab969ca5/newt.webp",
  "title": "",
  "width": 2880
}

1. マルチタイプフィールドを使う方法

マルチタイプフィールドを利用して、画像の情報を取得します。

1-1. フィールドの設定

モデル設定から、マルチタイプフィールドを追加します。
「使用できるフィールドタイプ」として、リッチテキストフィールド(またはマークダウンフィールド)と画像フィールドを設定します。
また、オプションの「複数値」を有効にしましょう。

set-attributes3.png

1-2. コンテンツの入稿

続いて、コンテンツを入稿します。
画像以外の部分をリッチテキストフィールドで入稿し、画像を画像フィールドで入稿します。

set-attributes4.png

ここでは、以下のように入力します。
画像の部分は画像フィールドに入力し、画像以外の部分をリッチテキストフィールドに入力しています。

set-attributes5.jpg

すると、CDN APIで取得するコンテンツは以下のようになります。
マルチタイプフィールド内のリッチテキストフィールドを用いた場合は、「"type": "RICH_TEXT"」として入力され、画像フィールドを用いた場合は、「"type": "IMAGE"」として入力されていることがわかります。

{
  "_id": "667cd227c034b1bff6acc0d6",
  "_sys": {
    (省略)
  },
  "title": "sample",
  "body": [
    {
      "_id": "667cd883e7329310e1020c2a",
      "type": "RICH_TEXT",
      "data": "<p>1枚目の画像までの文章をここに記載します。</p>"
    },
    {
      "_id": "667cd8cae7329310e1020dd7",
      "type": "IMAGE",
      "data": {
        "_id": "667cd3fec034b1bff6b2aa6d",
        "altText": "hogehoge",
        "description": "",
        "fileName": "newt.webp",
        "fileSize": 142662,
        "fileType": "image/webp",
        "height": 1400,
        "metadata": {},
        "src": "https://xxxxxx.assets.newt.so/v1/0971bfec-df41-4ef2-86ab-096dab969ca5/newt.webp",
        "title": "",
        "width": 2880
      }
    },
    {
      "_id": "667cd8dce7329310e1020df3",
      "type": "RICH_TEXT",
      "data": "<p>1枚目の画像から2枚目の画像までの文章をここに記載します。</p>"
    },
    {
      "_id": "667cd8f4e7329310e1020eeb",
      "type": "IMAGE",
      "data": {
        "_id": "667cd3fec034b1bff6b2aa6d",
        "altText": "hogehoge",
        "description": "",
        "fileName": "newt.webp",
        "fileSize": 142662,
        "fileType": "image/webp",
        "height": 1400,
        "metadata": {},
        "src": "https://xxxxxx.assets.newt.so/v1/0971bfec-df41-4ef2-86ab-096dab969ca5/newt.webp",
        "title": "",
        "width": 2880
      }
    },
    {
      "_id": "667cd8fde7329310e1020f11",
      "type": "RICH_TEXT",
      "data": "<p>2枚目の画像以降の文章をここに記載します。</p>"
    }
  ]
}

1-3. フロントエンドでの利用

例えば、Next.jsで dangerouslySetInnerHTML を利用する場合は、以下のように場合分けを行うことで、リッチテキストと画像を出し分けます。
取得した画像情報から、img要素のsrc・alt・width・height属性に値を設定できているのがわかります。

import type { Image } from 'newt-client-js'

(省略)

export default async function Post({ params }: Props) {
  const { slug } = params
  const post = await getPostBySlug(slug)
  if (!post) return

  return (
    <main className={styles.main}>
      <h1>{post.title}</h1>
      {post.body.map((block) => {
        switch (block.type) {
          case 'RICH_TEXT':
            return <div dangerouslySetInnerHTML={{ __html: block.data }} />
          case 'IMAGE':
            const image = block.data as Image
            return (
              // eslint-disable-next-line @next/next/no-img-element
              <img
                src={image.src}
                alt={image.altText}
                width={image.width}
                height={image.height}
              />
            )
          default:
            return <></>
        }
      })}
    </main>
  )
}

2. コンテンツに画像フィールドを追加し、リッチテキストのimg要素から画像の情報を取得可能にする方法

画像フィールド(複数値)を追加して、画像の情報を取得します。

2-1. フィールドの設定

本文の入力にリッチテキストフィールドを利用しているとします。

set-attributes8.png

モデル設定から、画像フィールドを追加します。
オプションの「複数値」も有効にしましょう。

set-attributes6.png

2-2. コンテンツの入稿

続いて、コンテンツを入稿します。
こちらでは、リッチテキストフィールドに画像も入力します。
そして、2-1で追加した画像フィールドに、リッチテキスト内で利用したすべての画像を登録します。

ここでは、以下のように入力します。

set-attributes7.png

2-3. フロントエンドでの利用

例えば、Next.jsで dangerouslySetInnerHTML を利用する場合は、以下のように cheerio 等を利用して、リッチテキスト内の画像情報を加工します。
画像フィールドの情報から、img要素のsrc・alt・width・height属性に値を設定できているのがわかります。

export default async function Post({ params }: Props) {
  const { slug } = params
  const post = await getPostBySlug(slug)
  if (!post) return

  const $ = load(post.body)
  $('img').replaceWith((_, elm) => {
    const image = post.images.find((image) => image.src === $(elm).attr('src'))
    if (image?.altText) {
      $(elm).attr('alt', image.altText)
    }
    if (image?.width) {
      $(elm).attr('width', image.width.toString())
    }
    if (image?.height) {
      $(elm).attr('height', image.height.toString())
    }
    return $(elm)
  })
  post.body = $.html()

  return (
    <main className={styles.main}>
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: post.body }} />
    </main>
  )
}

このように、画像情報を取得可能にすることで、リッチテキスト・マークダウン内のimg要素に属性を追加できます。
また、img要素ではなく、figure・figcaption要素を利用することでキャプションをつけることも可能です。

様々なアレンジをお試しください。

関連ドキュメント

NewtMade in Newt