barba-js について
barba-jsは、Barba.jsでページ遷移を実装するためのスキルです。複数ページのWebサイトを作る開発者向けに、ライフサイクルフック、ページ別処理、ルーティング、アニメーションのパターンを扱います。
主な機能
- 01全ページ再読み込みなしのAJAX遷移
- 02遷移を制御するライフサイクルフック
- 03名前空間によるページ別処理
- 04条件別・ルート別の遷移
- 05GSAPアニメーションのパターン
- 06セットアップツールとスターターテンプレート
活用シーン
- 01複数ページのWebサイトにアニメーション遷移を追加
- 02遷移後にページ固有の初期化を実行
- 03遷移元または遷移先に応じて遷移を選択
- 04Barba.jsの設定や遷移コードのひな形を生成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ freshtechbro/ claudedesignskills --skill barba-jsインストール後、Claude Code で/barba-jsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/README.mdreferences/api_reference.mdgsap_integration.mdhooks_guide.mdtransition_patterns.mdscripts/project_setup.pytransition_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 つの主要な要素:
-
Wrapper(
data-barba="wrapper")- 最も外側のコンテナ
- Wrapper 内で Container の外側にあるものはすべて維持されます
- 変更しないヘッダー、ナビゲーション、フッターに最適です
-
Container(
data-barba="container")- ナビゲーション時に更新される動的なコンテンツ領域
- トランジション中に置き換えられるのはこのセクションだけです
- すべてのページに存在する必要があります
-
Namespace(
data-barba-namespace="home")- ページタイプごとの一意の識別子
- トランジションルールとビューのロジックで使用されます
- 例:「home」、「about」、「product」、「blog-post」
2. トランジションのライフサイクル
Barba.js は各ナビゲーションで、明確なライフサイクルに従います。
デフォルトの非同期フロー:
- ユーザーがリンクをクリック
- Barba がナビゲーションをインターセプト
- 次のページをプリフェッチ(AJAX 経由)
- 新しいコンテンツをキャッシュ
- Leave フック — 現在のページをアニメーションで退出させる
- 退出アニメーションの完了を待機
- 古い Container を削除し、新しい Container を挿入
- Enter フック — 新しいページをアニメーションで表示する
- 表示アニメーションの完了を待機
- ブラウザーの履歴を更新
同期フロー(sync: true の場合):
- ユーザーがリンクをクリック
- Barba がナビゲーションをインターセプト
- 次のページをプリフェッチ
- 新しいページの読み込みを待機
- Leave フックと Enter フックを同時に実行(クロスフェード効果)
- Container を入れ替え
- ブラウザーの履歴を更新
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 ベースのページトランジションの代替アプローチ