📜

microCMSから記事タイトルを取得して、ニュースティッカーにして表示する。

2024/05/15に公開

microCMSから取得したニュース記事をスライダーで表示するニュースティッカーを作成する際の備忘録です。
フレームワークはNext.js、スライダーライブラリはswiperを使用しています。

フレームワーク・ライブラリ

  • Next.js 14.2.3
  • swiper 11.1.3
  • microcms-js-sdk 3.1.1
  • date-fns 3.6.0
  • date-fns-tz 3.1.3

DEMO

ニュースティッカーデモ

microCMSから記事情報の取得

公式の導入を参考に記事情報を取得しています。「Server Components - Dynamic Rendering」という項目まで、記事情報を取得する方法が記載されています。
microCMSとNext.js13 Server Components

DEMOソースコード

getNewsList 関数によって API からニュース記事が取得され、NewsTicker コンポーネントに渡されます。

app/page.tsx
import NewsTicker from "../components/NewsTicker";
import { getNewsList } from '@/libs/client';
import { LIMIT } from '@/constants';

export default async function Page() {
  const data = await getNewsList({
    limit: LIMIT,
  });
  return (
    <main className="flex-grow">
          <NewsTicker articles={data.contents}/>
    </main>
  );
}

NewsTicker コンポーネントは、articles としてニュース記事の配列を渡すと、記事タイトルが横スクロールするニュースティッカーとして表示します。
ニュースティッカーのスライドアニメーション設定は、Swiperのautoplay 設定により、一定時間ごとに自動的に記事が切り替わります。
必要に応じて、navigationpaginationなどのオプションを追加してカスタマイズすることができます。

components/NewsTicker/index.tsx
'use client';

import Link from 'next/link';
import { News } from '@/libs/client';
import { formatDate } from '@/libs/utils';
import { Swiper, SwiperSlide } from "swiper/react";
import { Autoplay } from 'swiper/modules';

import 'swiper/css'

type Props = {
    articles?: News[];
};

export default function NewsTicker({ articles }: Props) {

    if (!articles) {
        return null;
    }
    if (articles.length === 0) {
        return <p>記事がありません。</p>;
    }

    return (
        <section>
            <div className="flex text-center">
                <Swiper
                spaceBetween={30}
                centeredSlides={true}
                autoplay={{
                delay: 500,
                disableOnInteraction: false,
                }}
                modules={[Autoplay]}
                className="mySwiper"
                >
                    {articles.map((article) => (
                        <SwiperSlide key={article.id}>
                            <Link href={`/news/${article.id}`}>
                                {formatDate(article.publishedAt || article.createdAt)}:{article.title}
                            </Link>
                        </SwiperSlide>
                    ))}
                </Swiper>
            </div>
        </section>
    );
}

時刻データを取得して変換する処理

libs/utils.ts
import { format } from 'date-fns';
import { toZonedTime } from 'date-fns-tz';

/**
 * Formats a date string into a specific format.
 * @param date - The date string to be formatted.
 * @returns The formatted date string.
 */
export const formatDate = (date: string) => {
    const utcDate = new Date(date);
    const jstDate = toZonedTime(utcDate, 'Asia/Tokyo');
    return format(jstDate, 'd MMMM, yyyy');
  };
GitHubで編集を提案

Discussion