Blog

なんちゃって同画面遷移のカテゴリータブを作る

Cover Image for なんちゃって同画面遷移のカテゴリータブを作る

記事が増えてきて、このブログでは技術記事とポエム記事が乱立するっていうことがわかってきたので、ワンクリックで見たいカテゴリーの記事だけ表示できるタブを作ったよ。

同画面遷移させたい

ブログのタイトル下のカテゴリーをクリックしたら、記事一覧の部分だけおもむろに内容が更新されるようにしたかったよ。

その方が目に優しいし、アプリっぽくてかっこいい!

ステートを使わない方法

一部分だけDOMを変えるには、React hookとか使ってステート管理しないといけないのかなって思ったけど、

な、な、なんと!

Next.jsのLinkタグを使えばそれっぽい画面を簡単に作れることがわかったよ。

カテゴリーを作る

作り方の説明だよ。まず各記事にcategoryっていうメタ情報を追加したよ。

---
title: 'ユーザーにGoogle IDでログインさせるとシステム側が取得できる情報'
coverImage: "/assets/cover_images/20250114.png"
date: "2025-01-14T00:00:00"
ogImage:
  url: "/assets/cover_images/20250114.png"
category: Technology ←
tags:
  - Authentication
---

LINKタグを使ってカテゴリーページへのリンクを作る

サイトタイトルのすぐ下に各カテゴリーページへのリンクを表示するコンポーネントを作ったよ。

import Link from "next/link";

export default function CategorySwitcher() {
    return (
      <div className="flex flex-wrap justify-end mb-8 text-lg">
        // Linkタグを使ったリンクの羅列だよ
        <Link href="/" className="px-4 py-2 border-b-4 border-transparent hover:border-gray-900 dark:hover:border-gray-100 transition">All</Link>
        <Link href="/category/Technology" className="px-4 py-2 border-b-4 border-transparent hover:border-gray-900 dark:hover:border-gray-100 transition">Technology</Link>
        <Link href="/category/Lifestyle" className="px-4 py-2 border-b-4 border-transparent hover:border-gray-900 dark:hover:border-gray-100 transition">Lifestyle</Link>
      </div>
    );
}

Category Switcher

ホバーしたらアンダーバーが表示されるスタイルにしたよ。おしゃれ!

カテゴリーページを作る

タグ一覧を作ったのと同じ要領で/category/[slug]/page.tsxにカテゴリページを作ったよ。1カテゴリー1ページだよ。DOMはトップページとほとんど同じで、表示する記事だけフィルタリングしたものが取得できるようにしたよ。

import Container from "@/app/_components/container";
import { Intro } from "@/app/_components/intro";
import { Stories } from "@/app/_components/stories";
import { getAllPosts } from "@/lib/api";
import CategorySwitcher from "@/app/_components/category-switcher";

type Params = {
  params: Promise<{
    slug: string;
  }>;
};

export default async function Index(props: Params) {
  const params = await props.params;
  const posts = getPostsByCategory(params.slug);

  return (
    <main>
      <Container>
        <Intro />
        // さっき作ったCategorySwitcher
        <CategorySwitcher />
        <Stories posts={posts} />
      </Container>
    </main>
  );
}

// カテゴリーで絞り込んだ記事のリストを取得する.
function getPostsByCategory(category: string) {
  const allPosts = getAllPosts();
  const posts = allPosts.filter((post) => post.category === category);
  return posts;
}

出来上がり!

これでどうなるかというと...

カテゴリーをクリックすると、Linkタグで指定された/category/[slug]のページに遷移するよ。

Technologyクリック Technologyクリック

Lifestyleクリック Lifestyleクリック

つまり、同画面遷移ではないよ(笑)。でも、Linkタグを使っているから、ページがリロードされないで、記事一覧だけが切り替わるよ。URLは地味に変わるよ。でもそれ以外は微動だにしないよ。URL 見なかったら、同画面遷移に見えると思う!

onClickとか書かないでこんなに簡単に同画面遷移っぽいことができるなんてびっくらぽんだよー