📷

Astro にJSXを持っていったら画像が表示されなかった話

2023/11/21に公開

最近、ReactのちっさなプロジェクトをAstroに移行させたのですが、そのときJSXファイル内で指定している画像が表示されずにちょっとハマったので、備忘録として残しておきます。

結論としては、<img>タグのsrc属性は{インポート名.src}で指定する、というお話です。

Astroの画像の出力について

Astroでローカル画像を表示させる方法には、普通に使う<img>タグと、Astroに組み込まれている<Image>コンポーネントを使用できます。
astroファイル内ではImageコンポーネントを使用できます。

<Image /> (astro:assets)
Astro組み込みの<Image />コンポーネントを使用して、ローカル画像と設定済みのリモート画像の>最適化版を表示できます。
public/フォルダ内の画像とプロジェクトで明示的に設定されていないリモート画像もImageコン>>ポーネントで使用できますが、最適化処理はおこなわれません。
<Image />は、ローカルまたは許可されたリモート画像のサイズ、ファイルタイプ、品質を変換して、表示される画像を制御します。生成された<img>タグには、alt、loading、decoding属性が含まれており、また Cumulative Layout Shift(CLS) を回避するために画像のサイズを推測します。

https://docs.astro.build/ja/guides/images/#image--astroassets

Imageコンポーネントの使い方は非常に簡単で、importした画像ファイルをsrcに指定するだけです。

---
// Imageコンポーネントと画像をインポートする
import { Image } from 'astro:assets';
import myImage from "../assets/my_image.png"; // 画像は1600x900
---

<!-- `alt`はImageコンポーネントでは必須です -->
<Image src={myImage} alt="画像の説明。" />

出力結果は以下のようになります。

<img
  src="/_astro/my_image.hash.webp"
  width="1600"
  height="900"
  decoding="async"
  loading="lazy"
  alt="画像の説明。"
/>

<img>タグでの出力

astroプロジェクト内でReactなどJSX記法のフレームワークを使用する場合、Astroのイメージコンポーネントは使えません。この場合<img>タグを使用する必要があります。

import Image01 from '../images/img01.png';

export default function ImageComponent() {
  return(
    <div>
      <img src={Image01} alt="" />
    </div>
  )
}

しかし上記のように書くとエラーになります。
正しくは下記です。

import Image01 from '../images/img01.png';

export default function ImageComponent() {
  return(
    <div>
      <img src={Image01.src} alt="" />
    </div>
  )
}

画像のパスを指定するにはsrcプロパティにアクセスする必要があります。

インポートしている"Image01"をconsole.logで出力してみると以下のようになっています。

{
  src: '/~/src/images/hoge.png?origWidth=***&origHeight=***&origFormat=png',
  width: ***,
  height: ***,
  format: 'png'
}

Reactではわざわざプロパティにアクセスしなくても出力できたんですが、Astroの場合はimportした画像をオブジェクトとして持ってくれるため、プロパティにアクセスしないといけないみたいです。

Discussion