Next.js×Reactで作るスワイプ型LP実装ガイド Swiper.jsからGA4計測まで完全網羅
本記事では、Next.js(React)を用いて「スワイプ型LP(縦型スワイプLP)」を一から実装する手順を詳細に解説します。まずはプロジェクトのセットアップと主要ライブラリ(Swiper.js/react-swipeable+Tailwind CSS)の導入方法を説明し、フォルダ構成やコンポーネント設計をベストプラクティスとしてご紹介。スワイプコンテナの基本実装から、ダイナミックに渡すスライドデータの設計、Next.js標準のnext/imageによる画像最適化、レスポンシブ設定まで網羅します。
後半では、Google Analytics 4を用いた「スライド到達イベント」の計測実装例や、SSR/SSGを活かしたパフォーマンス最適化、next-seoによるSEO・アクセシビリティ対応、JestやCypressを用いたテスト戦略、そしてVercelへのCI/CDデプロイ設定まで、運用フェーズで欠かせない技術要素を一気通貫で押さえます。
Next.jsプロジェクトにスワイプ型LPを組み込みたいエンジニアの方なら、本記事だけで設計からテスト・デプロイまでの全工程を実践できる内容です。ぜひ、Reactの最新機能とNext.jsの強力なフレームワーク機能を活用して、高機能かつ分析可能なスワイプ型LPを構築してください。
なお、スワイプ型LPのメリットなどについては【実践事例付き】スワイプ型LPでCVR2倍を実現するテクニックで紹介しています。
システム開発が可能に
無料トライアル受付中!
前提条件・環境準備
まずは Next.js プロジェクトの新規作成から。TypeScript を使う場合は以下のコマンドでセットアップします。
npx create-next-app@latest swipe-lp --typescript
cd swipe-lp
依存ライブラリとしては、
- Swiper.js(公式 React ラッパー)
- react-swipeable(軽量ジェスチャー制御)
- Tailwind CSS(ユーティリティファーストのスタイリング)
- next-seo(SEO 管理)
- Google Analytics 4(計測用)
をインストールしておきましょう。なお、next-seoの使い方についてはNext.jsとヘッドレスCMSを使ったブログのSEO対策をNext-SEOで自動化するで紹介しています。
pnpm add swiper react-swipeable tailwindcss next-seo
Tailwind CSS のセットアップは公式ドキュメントに従います。tailwind.config.js
を生成し、./styles/globals.css
にベースディレクティブを追加してください。
プロジェクト構成とフォルダ設計
規模が大きくなっても保守しやすいよう、今回は以下のような構成とします。
/app
/layout.tsx ← 共通レイアウト(<html>/<body>)
/page.tsx ← ルートページ(スワイプLP)
/components
/SwipeContainer
index.tsx ← client component
SwipeContainer.module.css
/Slide
index.tsx ← client component
Slide.module.css
/Pagination
index.tsx ← client component
/lib
/analytics
ga.ts ← GA4イベント送信ラッパー
/globals.css ← 全体グローバルCSS(Tailwind base含む)
/next-seo.config.js ← next-seo 設定
App Router では、app/page.tsx
はデフォルトで Server Component になります。クライアントサイドのスワイプ操作を行うコンポーネントのみ 'use client'
を先頭に書いて Client Component として切り分けます。
コンポーネントの実装
スワイプコンテナの実装(Client Component)
app/components/SwipeContainer/index.tsx
を以下のように作成し、ファイル先頭に 'use client'
を記述します。
'use client';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css';
import { Navigation, Pagination } from 'swiper';
import styles from './SwipeContainer.module.css';
interface SwipeContainerProps {
slides: React.ReactNode[];
}
export default function SwipeContainer({ slides }: SwipeContainerProps) {
return (
<Swiper
direction="vertical"
slidesPerView={1}
pagination={{ clickable: true }}
navigation
modules={[Pagination, Navigation]}
className={styles.swipeContainer}
>
{slides.map((slide, i) => (
<SwiperSlide key={i}>{slide}</SwiperSlide>
))}
</Swiper>
);
}
スライドコンテンツの実装(Client Component)
各スライドは動的にコンテンツを受け取る汎用コンポーネントとして定義します。同様に 'use client'
を先頭に記述してください。
'use client';
import Image from 'next/image';
interface SlideProps {
title: string;
description: string;
imageSrc: string;
}
export default function Slide({ title, description, imageSrc }: SlideProps) {
return (
<section className="flex flex-col items-center justify-center h-screen p-4">
<h2 className="text-2xl font-bold mb-2">{title}</h2>
<p className="text-base mb-4">{description}</p>
<Image src={imageSrc} width={300} height={200} alt={title} />
</section>
);
}
ここで、next/image
を使うことで画像最適化と遅延読み込みをさせていますが、状況に応じて設定を最適化します。
ルートページの実装
データ取得や SEO 設定を含むルートページは、app/page.tsx
に記述します。
import SwipeContainer from './components/SwipeContainer';
import Slide from './components/Slide';
import { metadata } from '../next-seo.config';
export const metadata = {
...metadata,
title: 'Next.js App Routerで作るスワイプ型LP|完全実装ガイド',
};
const slidesData = [
{
title: '魅力的なコンセプト提示',
description: '第一スライドで製品のUSPを鮮烈にアピールします。',
imageSrc: '/images/slide1.jpg',
},
// 以降のスライドデータ…
];
export default function Page() {
const slides = slidesData.map((data, idx) => (
<Slide
key={idx}
title={data.title}
description={data.description}
imageSrc={data.imageSrc}
/>
));
return <SwipeContainer slides={slides} />;
}
動的に CMS から取得する場合は、await fetch()
を page.tsx
内で直接呼び出すか、別ファイルで export async function generateStaticParams()
を使ってデータフェッチをします。
レスポンシブ対応とタッチジェスチャー最適化
Swiper.js の breakpoints オプションを活用し、スクリーン幅に応じて挙動を変えます。SwipeContainer に次のように追加できます。
<Swiper
direction="vertical"
slidesPerView={1}
pagination={{ clickable: true }}
breakpoints={{
768: { direction: 'horizontal', slidesPerView: 2 },
}}
modules={[Pagination, Navigation]}
>
上記の場合、スマートフォンでは縦スワイプ(direction: 'vertical'
)となり、タブレット以上の画面サイズを保つ場合は横スワイプかつ複数枚表示(slidesPerView: 2
)…のように切り替えがされます。
パフォーマンス最適化
App Router では、ルートページ自体が Server Component なので、ビルド時にデータを取得して静的出力(SSG)がデフォルトで効きます。重いライブラリ(例:Swiper.js)をクライアントバンドルにのみ含めたい場合は、動的インポートを使って SSR をオフにします。
import dynamic from 'next/dynamic';
const SwipeContainer = dynamic(
() => import('./components/SwipeContainer'),
{ ssr: false }
);
これにより、Server Bundle のサイズを小さく保ちつつクライアントでのみスワイプ UI を読み込めます。
離脱ポイントの計測と分析
GA4 計測用に、app/lib/analytics/ga.ts
にラッパー関数を用意します。
export const trackSlideView = (index: number) => {
window.gtag('event', 'swipe_slide_view', {
slide_index: index,
});
};
SwipeContainer
の onSlideChange
イベントで呼び出せば、スライド到達時のインデックスを GA4 に送信できます。
<Swiper onSlideChange={({ activeIndex }) => trackSlideView(activeIndex)}>
SEO・アクセシビリティ対応
- metadata:
app/page.tsx
のexport const metadata
でタイトル・メタ説明を設定 - aria 属性:ナビゲーションボタンに
aria-label="次のスライドへ移動"
を追加 - 構造化:スライド順序を DOM 順に保ち、スクリーンリーダーでも自然に読めるようにする
さらに next-seo を使ってサイト全体の Open Graph や Twitter Card を管理すると、SNS でのシェア時にも最適化されたプレビューが生成されます。
next-seoの使い方についてはNext.jsとヘッドレスCMSを使ったブログのSEO対策をNext-SEOで自動化するで紹介しています。
まとめと今後の拡張
以上が Next.js の App Router を活用したスワイプ型LP構築の全工程です。Server/Client コンポーネントの分離、動的インポート、metadata API など、新しい機能を駆使することで、保守性・パフォーマンス・SEO を両立しながら高度な指ジェスチャー体験を提供できます。
今後は、ユーザー属性に応じてスライド内容を動的に変更するパーソナライズ機能や、A/B テストとの連携、さらには AR ネイティブコンテンツへの誘導といった次世代の拡張も検討してみてください。ぜひ本ガイドを参考に、App Router の強みを活かした高機能スワイプ型LPを開発してください。