mcpField
B
barba-js

barba-js

github.com/freshtechbroデザイン・UI1.2k2.4k 回インストール49 週間前に更新
リポジトリ

barba-js について

barba-jsは、Barba.jsでページ遷移を実装するためのスキルです。複数ページのWebサイトを作る開発者向けに、ライフサイクルフック、ページ別処理、ルーティング、アニメーションのパターンを扱います。

主な機能

  1. 01全ページ再読み込みなしのAJAX遷移
  2. 02遷移を制御するライフサイクルフック
  3. 03名前空間によるページ別処理
  4. 04条件別・ルート別の遷移
  5. 05GSAPアニメーションのパターン
  6. 06セットアップツールとスターターテンプレート

活用シーン

  1. 01複数ページのWebサイトにアニメーション遷移を追加
  2. 02遷移後にページ固有の初期化を実行
  3. 03遷移元または遷移先に応じて遷移を選択
  4. 04Barba.jsの設定や遷移コードのひな形を生成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/freshtechbro/claudedesignskills --skill barba-js

インストール後、Claude Code で/barba-jsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/
README.md
references/
api_reference.md
gsap_integration.md
hooks_guide.md
transition_patterns.md
scripts/
project_setup.py
transition_generator.py

詳細

Barba.js

ウェブサイトのページ間で、流れるような滑らかなトランジションを実現するためのモダンなページ遷移ライブラリです。Barba.js はナビゲーションを制御し、ページ全体を再読み込みせずにトランジションを管理することで、複数ページのウェブサイトをシングルページアプリケーション(SPA)のように動作させます。

概要

Barba.js は、ページ間のナビゲーションをインターセプトし、AJAX 経由で新しいコンテンツを取得して、古いコンテナと新しいコンテナの間を滑らかにトランジションさせる、軽量(圧縮・縮小後 7kb)の JavaScript ライブラリです。従来の複数ページアーキテクチャの利点を維持しながら、ページ読み込みの遅延と HTTP リクエストを削減します。

主な機能:

  • ページ全体を再読み込みしない滑らかなページトランジション
  • トランジションの各段階を正確に制御するライフサイクルフック
  • ページ固有の動作を実現するビュー単位のロジック
  • @barba/router プラグインによる組み込みルーティング
  • 拡張可能なプラグインシステム
  • 小さなフットプリントと高いパフォーマンス
  • フレームワークに依存しない設計(バニラ JS、GSAP、anime.js などで動作)

主な概念

1. Wrapper、Container、Namespace

Barba.js はトランジションを管理するために、特定の DOM 構造を使用します。

HTML 構造:

<body data-barba="wrapper">
  
  <header>
    <nav>
      <a href="/">Home</a>
      <a href="/about">About</a>
    </nav>
  </header>

  
  <main data-barba="container" data-barba-namespace="home">
    
    <h1>Home Page</h1>
    <p>Content that will transition out...</p>
  </main>

  
  <footer>© 2025</footer>
</body>

3 つの主要な要素:

  1. Wrapper(data-barba="wrapper")

    • 最も外側のコンテナ
    • Wrapper 内で Container の外側にあるものはすべて維持されます
    • 変更しないヘッダー、ナビゲーション、フッターに最適です
  2. Container(data-barba="container")

    • ナビゲーション時に更新される動的なコンテンツ領域
    • トランジション中に置き換えられるのはこのセクションだけです
    • すべてのページに存在する必要があります
  3. Namespace(data-barba-namespace="home")

    • ページタイプごとの一意の識別子
    • トランジションルールとビューのロジックで使用されます
    • 例:「home」、「about」、「product」、「blog-post」
2. トランジションのライフサイクル

Barba.js は各ナビゲーションで、明確なライフサイクルに従います。

デフォルトの非同期フロー:

  1. ユーザーがリンクをクリック
  2. Barba がナビゲーションをインターセプト
  3. 次のページをプリフェッチ(AJAX 経由)
  4. 新しいコンテンツをキャッシュ
  5. Leave フック — 現在のページをアニメーションで退出させる
  6. 退出アニメーションの完了を待機
  7. 古い Container を削除し、新しい Container を挿入
  8. Enter フック — 新しいページをアニメーションで表示する
  9. 表示アニメーションの完了を待機
  10. ブラウザーの履歴を更新

同期フロー(sync: true の場合):

  1. ユーザーがリンクをクリック
  2. Barba がナビゲーションをインターセプト
  3. 次のページをプリフェッチ
  4. 新しいページの読み込みを待機
  5. Leave フックと Enter フックを同時に実行(クロスフェード効果)
  6. Container を入れ替え
  7. ブラウザーの履歴を更新
3. フック

Barba には、トランジションを制御するための 11 個のライフサイクルフックがあります。

フックの実行順序:

Initial page load:
  beforeOnce → once → afterOnce

Every navigation:
  before → beforeLeave → leave → afterLeave →
  beforeEnter → enter → afterEnter → after

フックの種類:

  • グローバルフック:すべてのトランジションで実行されます(barba.hooks.before())
  • トランジションフック:特定のトランジションオブジェクト内に定義されます
  • ビューフック:ページ固有のロジックを実現するため、ビューオブジェクト内に定義されます

一般的なフックの用途:

  • beforeLeave — スクロール位置のリセット、アニメーションの準備
  • leave — 現在のページをアニメーションで退出させる
  • afterLeave — 古いページをクリーンアップ
  • beforeEnter — 新しいページを準備(要素を非表示にし、初期状態を設定)
  • enter — 新しいページをアニメーションで表示する
  • afterEnter — ページスクリプトとアナリティクストラッキングを初期化
4. ビュー

ビューは、Namespace に基づいて実行されるページ固有のロジックコンテナです。

barba.init({
  views: [{
    namespace: 'home',
    beforeEnter() {
      // Home-specific setup
      console.log('Entering home page');
    },
    afterEnter() {
      // Initialize home page features
      initHomeSlider();
    }
  }, {
    namespace: 'product',
    beforeEnter() {
      console.log('Entering product page');
    },
    afterEnter() {
      initProductGallery();
    }
  }]
});

一般的なパターン

1. 基本設定

インストール:

npm install --save-dev @barba/core
# or
yarn add @barba/core --dev

最小限の設定:

import barba from '@barba/core';

barba.init({
  transitions: [{
    name: 'default',
    leave({ current }) {
      // Fade out current page
      return gsap.to(current.container, {
        opacity: 0,
        duration: 0.5
      });
    },
    enter({ next }) {
      // Fade in new page
      return gsap.from(next.container, {
        opacity: 0,
        duration: 0.5
      });
    }
  }]
});
2. フェードトランジション(非同期)

クラシックなフェードアウト、フェードイントランジション:

import barba from '@barba/core';
import gsap from 'gsap';

barba.init({
  transitions: [{
    name: 'fade',
    async leave({ current }) {
      await gsap.to(current.container, {
        opacity: 0,
        duration: 0.5,
        ease: 'power2.inOut'
      });
    },
    async enter({ next }) {
      // Start invisible
      gsap.set(next.container, { opacity: 0 });

      // Fade in
      await gsap.to(next.container, {
        opacity: 1,
        duration: 0.5,
        ease: 'power2.inOut'
      });
    }
  }]
});
3. クロスフェードトランジション(同期)

ページ間で同時にフェードするトランジション:

barba.init({
  transitions: [{
    name: 'crossfade',
    sync: true, // Enable sync mode
    leave({ current }) {
      return gsap.to(current.container, {
        opacity: 0,
        duration: 0.8,
        ease: 'power2.inOut'
      });
    },
    enter({ next }) {
      return gsap.from(next.container, {
        opacity: 0,
        duration: 0.8,
        ease: 'power2.inOut'
      });
    }
  }]
});
4. オーバーラップするスライドトランジション

古いページをスライドして退出させながら、新しいページをオーバーラップさせて表示します。

barba.init({
  transitions: [{
    name: 'slide',
    sync: true,
    leave({ current }) {
      return gsap.to(current.container, {
        x: '-100%',
        duration: 0.7,
        ease: 'power3.inOut'
      });
    },
    enter({ next }) {
      // Start off-screen right
      gsap.set(next.container, { x: '100%' });

      // Slide in from right
      return gsap.to(next.container, {
        x: '0%',
        duration: 0.7,
        ease: 'power3.inOut'
      });
    }
  }]
});
5. トランジションルール(条件付きトランジション)

ナビゲーションの状況に応じて、異なるトランジションを定義します。

barba.init({
  transitions: [
    // Home to any page: fade
    {
      name: 'from-home-fade',
      from: { namespace: 'home' },
      leave({ current }) {
        return gsap.to(current.container, {
          opacity: 0,
          duration: 0.5
        });
      },
      enter({ next }) {
        return gsap.from(next.container, {
          opacity: 0,
          duration: 0.5
        });
      }
    },
    // Product to product: slide left
    {
      name: 'product-to-product',
      from: { namespace: 'product' },
      to: { namespace: 'product' },
      leave({ current }) {
        return gsap.to(current.container, {
          x: '-100%',
          duration: 0.6
        });
      },
      enter({ next }) {
        gsap.set(next.container, { x: '100%' });
        return gsap.to(next.container, {
          x: '0%',
          duration: 0.6
        });
      }
    },
    // Default fallback
    {
      name: 'default',
      leave({ current }) {
        return gsap.to(current.container, {
          opacity: 0,
          duration: 0.3
        });
      },
      enter({ next }) {
        return gsap.from(next.container, {
          opacity: 0,
          duration: 0.3
        });
      }
    }
  ]
});
6. ルートベースのトランジションに対応する Router プラグイン

@barba/router を使用して、ルート固有のトランジションを設定します。

インストール:

npm install --save-dev @barba/router

使用方法:

import barba from '@barba/core';
import barbaPrefetch from '@barba/prefetch';
import barbaRouter from '@barba/router';

// Define routes
barbaRouter.init({
  routes: [
    { path: '/', name: 'home' },
    { path: '/about', name: 'about' },
    { path: '/products/:id', name: 'product' }, // Dynamic segment
    { path: '/blog/:category/:slug', name: 'blog-post' }
  ]
});

barba.use(barbaRouter);
barba.use(barbaPrefetch); // Optional: prefetch on hover

barba.init({
  transitions: [{
    name: 'product-transition',
    to: { route: 'product' }, // Trigger on route name
    leave({ current }) {
      return gsap.to(current.container, {
        scale: 0.95,
        opacity: 0,
        duration: 0.5
      });
    },
    enter({ next }) {
      return gsap.from(next.container, {
        scale: 1.05,
        opacity: 0,
        duration: 0.5
      });
    }
  }]
});
7. ローディングインジケーター

ページの取得中に読み込み状態を表示します。

barba.init({
  transitions: [{
    async leave({ current }) {
      // Show loader
      const loader = document.querySelector('.loader');
      gsap.set(loader, { display: 'flex', opacity: 0 });
      gsap.to(loader, { opacity: 1, duration: 0.3 });

      // Fade out page
      await gsap.to(current.container, {
        opacity: 0,
        duration: 0.5
      });
    },
    async enter({ next }) {
      // Hide loader
      const loader = document.querySelector('.loader');
      await gsap.to(loader, { opacity: 0, duration: 0.3 });
      gsap.set(loader, { display: 'none' });

      // Fade in page
      await gsap.from(next.container, {
        opacity: 0,
        duration: 0.5
      });
    }
  }]
});

統合パターン

GSAP との統合

Barba.js は GSAP とシームレスに連携し、アニメーションを実行できます。

タイムラインベースのトランジション:

import barba from '@barba/core';
import gsap from 'gsap';

barba.init({
  transitions: [{
    async leave({ current }) {
      const tl = gsap.timeline();

      tl.to(current.container.querySelector('h1'), {
        y: -50,
        opacity: 0,
        duration: 0.3
      })
      .to(current.container.querySelector('.content'), {
        y: -30,
        opacity: 0,
        duration: 0.3
      }, '-=0.2')
      .to(current.container, {
        opacity: 0,
        duration: 0.2
      });

      await tl.play();
    },
    async enter({ next }) {
      const tl = gsap.timeline();

      // Set initial states
      gsap.set(next.container, { opacity: 0 });
      gsap.set(next.container.querySelector('h1'), { y: 50, opacity: 0 });
      gsap.set(next.container.querySelector('.content'), { y: 30, opacity: 0 });

      tl.to(next.container, {
        opacity: 1,
        duration: 0.2
      })
      .to(next.container.querySelector('h1'), {
        y: 0,
        opacity: 1,
        duration: 0.5,
        ease: 'power3.out'
      })
      .to(next.container.querySelector('.content'), {
        y: 0,
        opacity: 1,
        duration: 0.5,
        ease: 'power3.out'
      }, '-=0.3');

      await tl.play();
    }
  }]
});

高度な GSAP の統合パターンについては、gsap-scrolltrigger スキルを参照してください。

ページ固有の初期化

ページごとにライブラリやスクリプトを初期化します。

barba.init({
  views: [
    {
      namespace: 'home',
      afterEnter() {
        // Initialize home page features
        initHomepageSlider();
        initParallaxEffects();
      },
      beforeLeave() {
        // Clean up
        destroyHomepageSlider();
      }
    },
    {
      namespace: 'gallery',
      afterEnter() {
        initLightbox();
        initMasonry();
      },
      beforeLeave() {
        destroyLightbox();
      }
    }
  ]
});
アナリティクスのトラッキング

ページ遷移時にページビューをトラッキングします。

barba.hooks.after(() => {
  // Google Analytics
  if (typeof gtag !== 'undefined') {
    gtag('config', 'GA_MEASUREMENT_ID', {
      page_path: window.location.pathname
    });
  }

  // Or use data layer
  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    event: 'pageview',
    page: window.location.pathname
  });
});
サードパーティ製スクリプトの再初期化

ページのトランジション後にスクリプトを再実行します。

barba.hooks.after(() => {
  // Re-initialize third-party widgets
  if (typeof twttr !== 'undefined') {
    twttr.widgets.load(); // Twitter widgets
  }

  if (typeof FB !== 'undefined') {
    FB.XFBML.parse(); // Facebook widgets
  }

  // Re-run syntax highlighting
  if (typeof Prism !== 'undefined') {
    Prism.highlightAll();
  }
});

パフォーマンスの最適化

1. プリフェッチ

@barba/prefetch を使って、ホバー時にページを読み込みます。

npm install --save-dev @barba/prefetch
import barba from '@barba/core';
import barbaPrefetch from '@barba/prefetch';

barba.use(barbaPrefetch);

barba.init({
  // Prefetch fires on link hover by default
  prefetch: {
    root: null, // Observe all links
    timeout: 3000 // Cache timeout in ms
  }
});
2. レイアウトシフトの防止

コンテンツのジャンプを防ぐため、コンテナに最小の高さを設定します。

[data-barba="container"] {
  min-height: 100vh;
  /* Or use viewport height minus header/footer */
  min-height: calc(100vh - 80px - 60px);
}
3. アニメーションの最適化

GPU アクセラレーションに対応したプロパティを使用します。

// ✅ Good - GPU accelerated
gsap.to(element, {
  opacity: 0,
  x: -100,
  scale: 0.9,
  rotation: 45
});

// ❌ Avoid - causes reflow/repaint
gsap.to(element, {
  width: '50%',
  height: '300px',
  top: '100px'
});
4. イベントリスナーのクリーンアップ

beforeLeave またはビューのフックでリスナーを削除します。

barba.init({
  views: [{
    namespace: 'home',
    afterEnter() {
      // Add listeners
      this.clickHandler = () => console.log('clicked');
      document.querySelector('.btn').addEventListener('click', this.clickHandler);
    },
    beforeLeave() {
      // Remove listeners
      document.querySelector('.btn').removeEventListener('click', this.clickHandler);
    }
  }]
});
5. 画像の遅延読み込み

トランジション後まで画像の読み込みを遅らせます。

barba.init({
  transitions: [{
    async enter({ next }) {
      // Complete transition first
      await gsap.from(next.container, {
        opacity: 0,
        duration: 0.5
      });

      // Then load images
      const images = next.container.querySelectorAll('img[data-src]');
      images.forEach(img => {
        img.src = img.dataset.src;
        img.removeAttribute('data-src');
      });
    }
  }]
});

よくある落とし穴

1. Promise の返し忘れ

問題:アニメーションの完了を待たずにトランジションが即座に終了します。

解決策:必ず Promise を返すか、async/await を使います。

// ❌ Wrong - animation starts but doesn't wait
leave({ current }) {
  gsap.to(current.container, { opacity: 0, duration: 0.5 });
}

// ✅ Correct - returns promise
leave({ current }) {
  return gsap.to(current.container, { opacity: 0, duration: 0.5 });
}

// ✅ Also correct - async/await
async leave({ current }) {
  await gsap.to(current.container, { opacity: 0, duration: 0.5 });
}
2. リンクのデフォルト動作を防止していない

問題:一部のリンクでページ全体が再読み込みされます。

解決策:Barba は内部リンクのデフォルト動作を自動的に防止しますが、外部リンクを除外する必要がある場合があります。

barba.init({
  prevent: ({ href }) => {
    // Allow external links
    if (href.indexOf('http') > -1 && href.indexOf(window.location.host) === -1) {
      return true;
    }
    return false;
  }
});
3. ページ間の CSS の競合

問題:古いページの CSS がトランジション中に新しいページのレイアウトへ影響します。

解決策:名前空間固有の CSS を使うか、スタイルをリセットします。

/* Namespace-specific styles */
[data-barba-namespace="home"] .hero {
  background: blue;
}

[data-barba-namespace="about"] .hero {
  background: red;
}

または、beforeEnter でリセットします。

beforeEnter({ next }) {
  // Reset scroll position
  window.scrollTo(0, 0);

  // Reset any global state
  document.body.classList.remove('menu-open');
}
4. ドキュメントタイトルとメタタグを更新していない

問題:ページ遷移時にページタイトルとメタタグが更新されません。

解決策:@barba/head プラグインを使うか、手動で更新します。

npm install --save-dev @barba/head
import barba from '@barba/core';
import barbaHead from '@barba/head';

barba.use(barbaHead);

barba.init({
  // Head plugin automatically updates <head> tags
});

または、手動で更新します。

barba.hooks.after(({ next }) => {
  // Update title
  document.title = next.html.querySelector('title').textContent;

  // Update meta tags
  const newMeta = next.html.querySelectorAll('meta');
  newMeta.forEach(meta => {
    const name = meta.getAttribute('name') || meta.getAttribute('property');
    if (name) {
      const existing = document.querySelector(`meta[name="${name}"], meta[property="${name}"]`);
      if (existing) {
        existing.setAttribute('content', meta.getAttribute('content'));
      }
    }
  });
});
5. ページ表示時のアニメーションのちらつき

問題:ページ表示時のアニメーションが始まる前に、新しいページがちらついて表示されます。

解決策:CSS または beforeEnter で初期状態を非表示に設定します。

/* CSS approach */
[data-barba="container"] {
  opacity: 0;
}

[data-barba="container"].is-visible {
  opacity: 1;
}
// JavaScript approach
beforeEnter({ next }) {
  gsap.set(next.container, { opacity: 0 });
}
6. 適切な位置指定をしていない同期トランジション

問題:コンテナが積み重なることで、同期トランジション時にレイアウトシフトが発生します。

解決策:トランジション中はコンテナを絶対位置に配置します。

[data-barba="wrapper"] {
  position: relative;
}

[data-barba="container"] {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
}

または、JavaScript で制御します。

barba.init({
  transitions: [{
    sync: true,
    beforeLeave({ current }) {
      gsap.set(current.container, {
        position: 'absolute',
        top: 0,
        left: 0,
        width: '100%'
      });
    }
  }]
});

リソース

このスキルには以下が含まれます。

scripts/

一般的な Barba.js タスク向けの実行可能なユーティリティ:

  • transition_generator.py - トランジションのボイラープレートコードを生成します
  • project_setup.py - Barba.js のプロジェクト構成を初期化します
references/

詳細なドキュメント:

  • api_reference.md - Barba.js API の完全なリファレンス(フック、トランジション、ビュー、ルーター)
  • hooks_guide.md - 実行順序とユースケースを含む、11 個すべてのフックのガイド
  • gsap_integration.md - Barba のトランジション向け GSAP アニメーションパターン
  • transition_patterns.md - 一般的なトランジションの実装
assets/

テンプレートとスタータープロジェクト:

  • starter_barba/ - Barba.js と GSAP を組み合わせた完全なスターターテンプレート
  • examples/ - 実際のトランジションの実装例

関連スキル

  • gsap-scrolltrigger - トランジションで高度な GSAP アニメーションを使う場合
  • locomotive-scroll - Barba と組み合わせて、ページ間のスムーズスクロールを実現できます
  • motion-framer - React ベースのページトランジションの代替アプローチ

コメント