Astro で Iconify を使うべく色々格闘した話

astroiconify
2023/09/05 に公開

結論

  • @iconify/iconifyを使って、SVG を直接生成した
  • SVG の生成をラップする Astro コンポーネントを自作した
Icon.astro
 ---
import Iconify from "@iconify/iconify"

interface Props {
  icon: string
  class?: string
}

const props = Astro.props

const getIconSvg = async (icon: string) => {
  await Iconify.loadIcon(icon)

  const iconData = Iconify.getIcon(icon)
  if (!iconData) throw new Error(`Icon ${icon} not found`)

  return (
    `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${iconData.left} ${iconData.top} ${iconData.width} ${iconData.height}" fill="none" style="width:100%">` +
    iconData.body +
    "</svg>"
  )
}
---

<div set:html={await getIconSvg(props.icon)} class={props.class} /> 

使い方:

App.astro
 <Icon class="w-32" icon="fluent-emoji:robot" /> 

試したこと

  • astro-icon: iconify のバージョンが古く、欲しいものが使えなかった。

  • @iconify/tailwind: iconの指定に変数を利用した際になぜか Icon が表示されず使えなかった。

    OK
     <span class="fluent-emoji:robot"></span> 
    NG
     ---
    const icon = "icon" + "-" + "[fluent-emoji--building-construction]"
    ---
    
    <span class={`${icon} text-8xl`}></span> 
  • @iconify/react: client サイドで javascrit を実行しないと画像が表示されないので、Astro との相性を考えて使わなかった。