Next.js で動的なルーティングをする

Next.js

udemy 教材のアウトプットです。

【NotionをCMSに】NotionAPI + Next.js + TypeScript でブログ開発〜デプロイまで
話題で便利なNotion。普段使用しているNotionをCMSとして、記事運用が快適で簡単になるブログアプリケーションを開発します。React、Nextjsフレームワークを使用し、TypeScriptで実装。最後はデプロイまで行います。

ルーティングしたいテンプレートページを作成する

WordPress のpage-contact.phpとかと同じような雰囲気?

pages 配下にarticlesフォルダを作成して、[slug].tsxを作成する。

これでとりあえずは、https://example.com/articles/****へアクセスできるようになる。

ルーティング元の href を設定する

const Card: React.FC<CardProps> = ({ page }) => {
  return (
    <Link href={`/articles/${page.slug}`} className="flex justify-center ">
      <div className="max-w-sm rounded overflow-hidden shadow-lg w-full my-4 md:my-0 content-between grid">
        {/* image */}
        <div>
          {" "}
          <Image className="w-full static h-auto" src={page.cover} alt="" objectFit="cover" width={400} height={225} quality={30} />
        </div>

        {/* title & date*/}
        <div className="px-6 pt-4 ">
          <h2 className="text-base font-medium mb-3 ">{page.name}</h2>
          <p className="text-gray-700 text-xs">{page.published}</p>
        </div>

        {/* tag */}
        <div className="px-6 pb-4 ">
          {page.tags.map((tag, index) => (
            <span key={index} className="text-sm px-2 py-1 font-normal bg-gray-200 rounded-lg break-words mr-2 mb-2">
              {`#${tag}`}
            </span>
          ))}
        </div>
      </div>
    </Link>
  );
};

記事をmapさせているところで、slugを設定しておいて/articles/***の***部分を指定する。

getServerSideProps の設定をする

import { GetServerSideProps } from "next";
import ArticleMeta from "../../components/ArticleMeta";
import Layout from "../../components/Layout";

export const getServerSideProps: GetServerSideProps = async () => {
  return {
    props: {
      slug: "yellow",
    },
  };
};
const Article = ({ slug }) => {
  return (
    <Layout>
      <article className="w-full">
        {/* meta section */}
        <div className="my-12">
          <ArticleMeta />
        </div>

        {/* article */}
        <div className="my-12">article {slug}</div>
      </article>
    </Layout>
  );
};

アクセスをするたびに、slug: 'yellow'が Article コンポーネントへ渡ってくるので、それをpropsとして受け取る。

yellow としていた部分を動的に切り替える(記事ごとに切り替える)

import { ParsedUrlQuery } from "querystring";

type Params = ParsedUrlQuery & {
  slug: string;
};
export const getServerSideProps: GetServerSideProps = async (ctx) => {
  const { slug } = ctx.params as Prams;
  return {
    props: {
      slug: sulg,
    },
  };
};
  • 引数として、contextが渡ってくるので、ctxで受け取る。
  • ctx.paramsへ参照することで、[slug].tsxslugの部分を参照できるようになる。
  • props の slug の value をslugへ変更する。

getServerSideProps 最終形

export const getServerSideProps: GetServerSideProps = async (ctx) => {
  const { slug } = ctx.params as Params;

  const page = sampleCards.find((data) => data.slug === slug);

  return {
    props: {
      page,
    },
  };
};

sampleCards のような配列や json を取得してslug が同じもののデータをreturnする。

それがArticleの props として渡って、記事の内容をレンダリングする。

タイトルとURLをコピーしました