Embla Carousel を Next.js で利用する
Web サイトのトップページやナビゲーションなどで利用されるスライドするコンポーネント、Carousel を Next.js App Router に実装します。今回は、Embra Carousel を利用します。
プロジェクトの作成
まず最初に、Next.js のプロジェクトを作成します。
npx create-next-app

スタイルのファイルを src/styles のフォルダを作成して globals.css を作成したフォルダに移動をします。そしてこのファイルを参照している src/app/layout.tsx のファイルの import を以下のように書き換えます。
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "@/styles/globals.css";
変更後、サンプルのページが表示されるか確認をしてください。
npm run dev

これで準備ができました。
Embla Carousel のインストール
React だけでなく、Vanilla いわゆる素の環境でも利用できるパッケージである Embla Carousel のパッケージを今回は利用します。このパッケージは非常に軽量に動くこともあり、利用実績も豊富です。
まずは簡単なサンプルが動くところまで進めてみます。
画像を用意する
サンプルが動いているのがわかるように、画像を用意します。今回は、unsplush を利用して、3つの画像を public の下に追加しました。猫の写真です。

パッケージのインストール
Embla Carousel のパッケージをインストールしていきます。今回は、オートプレイの機能も追加するため、2つのパッケージをインストールします。
npm install embla-carousel-react embla-carousel-autoplay
これで Embla Carousel を利用できるようになりました。
コンポーネントを作成する
Embla Carousel のサイトのサンプルのコードを参考にしながら、今回は以下のようなコンポーネントを作成しました。public にコピーをした画像を利用して、カルーセルとして動作する形となります。
"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 のファイルを作成して、以下のようにスタイルを指定します。
.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 のファイルで読み込みますが、サンプルで提供されているコードをこの機会に削除します。
@import "tailwindcss";
@import "./carousel.css";
カルーセルを利用する
利用する準備ができました。まず、トップページでコンポーネントを利用します。
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 のファイルもサンプルのコードを削除します。
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 のコンポーネントを以下のように書き換えます。
"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>
);
}
続いてスタイルシートを以下のように変更をします。
.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 で管理しているカルーセルのデータと連携するといった実装が可能なため、このベースとなる部分をまずは理解しておきましょう。