AstroとSvelteのコンポーネントを連携させる


DE-TEIUです。

このブログのソースコードのリファクタリングを実施するために、Svelteを導入してみました。

導入

公式ドキュメントを見る限り、このコマンドを打つだけでした。

$ npx astro add svelte

上記のコマンドで追加するだけで、astro.config.mjsにも自動で設定が追記されます。

import svelte from "@astrojs/svelte";

~~~

export default defineConfig({
  site: "https://hierophant.green",
  integrations: [mdx(), sitemap(), svelte(), tailwind()],
  ~~~
});

使ってみる

コンポーネントを作る

普通にSvelteで開発する時と同じように、適当なディレクトリに~~~.svelteファイルを作ります。

今回は、記事の末尾に表示するSNS共有リンクのコンポーネントをSvelteで書き直します。

<script lang="ts">
  export let currentURL: string;
  export let pageTitle: string;

  const tweetURL = `https://twitter.com/share?url=${encodeURIComponent(currentURL)}&text=${encodeURIComponent(pageTitle)}`;
</script>

<div class="flex items-center">
  <div class="flex mr-4">
    <!--Twitter -->
    <a
      class="flex bg-[#1da1f2] border-none rounded px-2 py-2 cursor-pointer"
      href={tweetURL}
      target="_blank"
      rel="noopener noreferrer"
    >
      <svg
        role="img"
        viewBox="0 0 24 24"
        xmlns="http://www.w3.org/2000/svg"
        width="24"
        height="24"
        fill="#ffffff"
      >
        <title>X</title>
        <path
          d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z"
        />
      </svg>
    </a>
  </div>
  <div class="flex mr-4">
    <!--はてなブックマーク -->
    <a
      href="https://b.hatena.ne.jp/entry/"
      class="hatena-bookmark-button"
      data-hatena-bookmark-layout="vertical-normal"
      data-hatena-bookmark-lang="ja"
      title="このエントリーをはてなブックマークに追加"
      ><img
        src="https://b.st-hatena.com/images/v4/public/entry-button/[email protected]"
        alt="このエントリーをはてなブックマークに追加"
        width="20"
        height="20"
        style="border: none;"
      />
    </a>
    <script
      type="text/javascript"
      src="https://b.st-hatena.com/js/bookmark_button.js"
      charset="utf-8"
      async
    ></script>
  </div>
</div>

はい。

Astro側からSvelteのコンポーネントを呼んでみる

特に難しいことはありません。作ったコンポーネントをインポートしてhtmlに配置していくだけです。

---
import SnsShare from "../components/SnsShare.svelte";

// コンポーネントに渡したいパラメータを用意
const { title, description, pubDate, updatedDate, heroImage } = Astro.props;
const currentURL = new URL(Astro.request.url).href;
const pageTitle = `${title} - ${SITE_TITLE}`;
---

そしてhtmlに配置するときはこんな感じです。パラメータも渡せます。簡単ですね。

<SnsShare currentURL={currentURL} pageTitle={pageTitle} />

ということで↓にそのコンポーネントが表示されています。以上。