Docs / tech

Embla Carousel を Next.js で利用する

2025-07-09 2025-07-29 |

Web サイトのトップページやナビゲーションなどで利用されるスライドするコンポーネント、Carousel を Next.js App Router に実装します。今回は、Embra Carousel を利用します。

プロジェクトの作成

まず最初に、Next.js のプロジェクトを作成します。

npx create-next-app

スタイルのファイルを src/styles のフォルダを作成して globals.css を作成したフォルダに移動をします。そしてこのファイルを参照している src/app/layout.tsx のファイルの import を以下のように書き換えます。

src/app/layout.tsx
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "@/styles/globals.css";

変更後、サンプルのページが表示されるか確認をしてください。

npm run dev

これで準備ができました。

React だけでなく、Vanilla いわゆる素の環境でも利用できるパッケージである Embla Carousel のパッケージを今回は利用します。このパッケージは非常に軽量に動くこともあり、利用実績も豊富です。

まずは簡単なサンプルが動くところまで進めてみます。

画像を用意する

サンプルが動いているのがわかるように、画像を用意します。今回は、unsplush を利用して、3つの画像を public の下に追加しました。猫の写真です。

パッケージのインストール

Embla Carousel のパッケージをインストールしていきます。今回は、オートプレイの機能も追加するため、2つのパッケージをインストールします。

npm install embla-carousel-react embla-carousel-autoplay

これで Embla Carousel を利用できるようになりました。

コンポーネントを作成する

Embla Carousel のサイトのサンプルのコードを参考にしながら、今回は以下のようなコンポーネントを作成しました。public にコピーをした画像を利用して、カルーセルとして動作する形となります。

src/components/Carousel.tsx
"use client";

import Image from "next/image";
import React from "react";
import useEmblaCarousel from "embla-carousel-react";
import Autoplay from "embla-carousel-autoplay";

export default function Carousel() {
	const [emblaRef] = useEmblaCarousel({ loop: false }, [Autoplay()]);

	return (
		<div className="embla" ref={emblaRef}>
			<div className="embla__container">
				<div className="embla__slide">
					<Image
						src="/ludemeula-fernandes-9UUoGaaHtNE-unsplash.jpg"
						alt="Slide 1"
						width={1920}
						height={1321}
						className="embla__image"
					/>
				</div>
				<div className="embla__slide">
					<Image
						src="/manja-vitolic-gKXKBY-C-Dk-unsplash.jpg"
						alt="Slide 2"
						width={1920}
						height={1321}
						className="embla__image"
					/>
				</div>
				<div className="embla__slide">
					<Image
						src="/michael-sum-LEpfefQf4rU-unsplash.jpg"
						alt="Slide 3"
						width={1920}
						height={1321}
						className="embla__image"
					/>
				</div>
			</div>
		</div>
	);
}

このページで利用しているスタイルシートとして、src/styles/carousel.css のファイルを作成して、以下のようにスタイルを指定します。

src/styles/carousel.css
.embla {
	@apply overflow-hidden;
}
.embla__container {
	@apply flex-col h-[300px] md:h-[500px];
}
.embla__slide {
	@apply flex-shrink-0 flex-grow-0 w-full min-w-0;
}

.embla__image {
	@apply h-[300px] md:h-[500px] object-cover;
}

このスタイルを利用できるように、globals.css のファイルで読み込みますが、サンプルで提供されているコードをこの機会に削除します。

src/styles/globals.css
@import "tailwindcss";
@import "./carousel.css";

カルーセルを利用する

利用する準備ができました。まず、トップページでコンポーネントを利用します。

src/app/page.tsx
import Carousel from "@/components/Carousel";

export default function Home() {
	return (
		<div>
			<h1 className="text-3xl font-bold mb-2">Next.js Carousel Sample</h1>
			<Carousel />
		</div>
	);
}

ついでに layout.tsx のファイルもサンプルのコードを削除します。

src/app/layout.tsx
import type { Metadata } from "next";
import "@/styles/globals.css";

export const metadata: Metadata = {
	title: "Create Next App",
	description: "Generated by create next app",
};

export default function RootLayout({
	children,
}: Readonly<{
	children: React.ReactNode;
}>) {
	return (
		<html lang="en">
			<body>{children}</body>
		</html>
	);
}

これで準備ができました。実行します。

npm run dev

画像がスライドで定期的に切り替わるようになります。

カルーセルの実装ができました。

ボタンの追加

現在は自動的に切り替わるだけとなっていますが、もう少し凝った形で左右のボタンを追加して、クリックをしたら前後に切り替える形として変更をします。

まずアイコンは Lucide Icons を利用します。

パッケージをインストールしてください。

npm install lucide-react

これでアイコンが利用できるようになります。Carousel のコンポーネントを以下のように書き換えます。

src/components/Carousel.tsx
"use client";

import Image from "next/image";
import React, { useCallback } from "react";
import useEmblaCarousel from "embla-carousel-react";
import Autoplay from "embla-carousel-autoplay";
import { ArrowLeft, ArrowRight } from "lucide-react";

export default function Carousel() {
	const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true }, [
		Autoplay({ delay: 4000, stopOnInteraction: false }),
	]);

	const scrollPrev = useCallback(() => {
		emblaApi?.scrollPrev();
	}, [emblaApi]);

	const scrollNext = useCallback(() => {
		emblaApi?.scrollNext();
	}, [emblaApi]);

	return (
		<div className="embla">
			<div className="embla__viewport" ref={emblaRef}>
				<div className="embla__container">
					<div className="embla__slide">
						<Image
							src="/ludemeula-fernandes-9UUoGaaHtNE-unsplash.jpg"
							alt="Slide 1"
							width={1920}
							height={1321}
							className="embla__image"
						/>
					</div>
					<div className="embla__slide">
						<Image
							src="/manja-vitolic-gKXKBY-C-Dk-unsplash.jpg"
							alt="Slide 2"
							width={1920}
							height={1321}
							className="embla__image"
						/>
					</div>
					<div className="embla__slide">
						<Image
							src="/michael-sum-LEpfefQf4rU-unsplash.jpg"
							alt="Slide 3"
							width={1920}
							height={1321}
							className="embla__image"
						/>
					</div>
				</div>
				<button
					onClick={scrollPrev}
					className="absolute left-4 top-1/2 -translate-y-1/2 bg-black/50 hover:bg-black/70 text-white p-2 rounded-full z-10"
				>
					<ArrowLeft className="w-6 h-6" />
				</button>

				<button
					onClick={scrollNext}
					className="absolute right-4 top-1/2 -translate-y-1/2 bg-black/50 hover:bg-black/70 text-white p-2 rounded-full z-10"
				>
					<ArrowRight className="w-6 h-6" />
				</button>
			</div>
		</div>
	);
}

続いてスタイルシートを以下のように変更をします。

src/styles/carousel.css
.embla {
	@apply relative w-full overflow-hidden;
}

.embla__container {
	@apply flex h-[300px] md:h-[500px];
}
.embla__slide {
	@apply flex-shrink-0 flex-grow-0 w-full min-w-0;
}

.embla__image {
	@apply h-[300px] md:h-[500px] object-cover;
}

変更後、以下のようにボタンが追加されます。

まとめ

今回は Embla Carousel のパッケージを利用して、カルーセルのコンポーネントを作成しました。サムネイルを表示してクリックしたら切り替える、という実装も可能です。詳しくは Embla Carousel の公式サイト、もしくは各種 Tips をご覧ください。

今回のサンプルをもとに、表示されているスライドをクリックしたらページが遷移する、CMS で管理しているカルーセルのデータと連携するといった実装が可能なため、このベースとなる部分をまずは理解しておきましょう。

参考情報