Astro + Swup で addEventListener が追加できない問題を解決する

 

2024/09/21

swupでは、ページの遷移アニメーションやページの事前ロードによる最適化ができます

カーソルを合わせた時やリンクが画面に入った時に事前ロードを発生させることで、表示を高速化できます

swup ドキュメント

@swup/astro

この

Intergration
を使うと、Astroのページ遷移のアニメーションやプリロードが簡単に実現できます

bash
# pnpmの場合
pnpm astro add react

# npmの場合
npx astro add react

# yarnの場合
yarn astro add react

このコマンドだけでAstroプロジェクトにswupを追加できます

このようなコードで、Astroのページにメニューを追加していました (Astroコンポーネントの説明は省略します、公式ドキュメントを見てください)

Astroテンプレートの構文

astro
  <a id="open">
    <Icon name="gravity-ui:dots-9" />
  </a>
  <div id="menu">
    <h2>menu</h2>
    <!-- メニューの内容 -->
    <a id="close">
      <Icon name="gravity-ui:xmark" />
    </a>
  </div>
  
  <script>
    import { gsap } from 'gsap'
    function init() {
      const open = document.getElementById('open')
      open.addEventListener('click', () => {
        gsap.to(menu, { display: 'block' })
      })
    }
    init()
  </script>

(classは省略しています)

このコンポーネントを各ページのLayoutに追加して使っていたのですが、ページを移動するとmenuが押せなくなる問題が発生しました

原因は、swupで移動した際に

eventListener
が初期化されてしまうからであることはすぐに分かったのですが、swupの遷移を検知して再登録(つまり
init()
を実行)をするのにとても悩みました

結論から言うと、以下の方法でイベントの再登録ができました

astro
  <script>
    import { gsap } from 'gsap'
    function init() {
      const open = document.getElementById('open')
      open.addEventListener('click', () => {
        gsap.to(menu, { display: 'block' })
      })
    }
    init()
    const setup = () => {
      (window as any).swup.hooks.on('page:view', init)
    }
    if ((window as any).swup) {
      setup()
    } else {
      document.addEventListener('swup:enable', setup)
    }
  </script>

同時に、

astro.config.mts
で以下の設定を有効にします

JavaScript
import { defineConfig } from 'astro/config'
import swup from '@swup/astro'

// https://astro.build/config
export default defineConfig({
  integrations: [
    swup({
      globalInstance: true, // この行を追加する
    }),
  ],
})

これによって、

  1. window.swup
    インスタンスが登録されたことを検知して、ページが開かれたことを検知するhooksを登録
  2. ページが開かれたことを検知して
    init()
    を実行
  3. init()
    によって
    EventListener
    を再登録

を実行でき、ページの遷移後もメニューを開けるようになりました🎉

2日ぐらい悩みました、これをやっている人がほとんどいなかったので情報がないに等しかったです

そこで

@swup/astro

README.md
を隅々まで見返してみると、下の方に
Note
として書いてあったのです、いやぁ気づかなかった!

情報がないときは公式を読み込むに限りますね

image

知見が見つからなかったので書いてみました!
参考になれば幸いです!!

このページの情報は以上です