Next.jsの動的ルーティングについて

# 前書き、概要
プログラミング学習中に、Next.js、Laravelを使用してRealWorldを作成しました。
その際、動的ルーティングに詰まったので忘れないように記録しておきます。
同じように詰まっている方の参考になれば幸いです。
## 使用バージョン
`Next.js　14.1.0`
# 目次
[動的ルーティングとは](#動的ルーティングとは)
[失敗例](#失敗例)
[解決した方法](#解決した方法)
[まとめ](#まとめ)
# 動的ルーティングとは
・リンク先のURLが正確に分からない
・もしくは渡されるパラメータによって表示する内容を変える
など動的なデータからルートを作成したい場合に対応できる機能。

https://nextjs.org/docs/pages/building-your-application/routing/dynamic-routes

## 設定方法
Next.jsリファレンスより
>For example, a blog could include the following route pages/blog/[slug].js where [slug] is the Dynamic Segment for blog posts.
>```TypeScript
>import { useRouter } from 'next/router'
> 
>export default function Page() {
>  const router = useRouter()
>  return <p>Post: {router.query.slug}</p>
>}
>```
>|Route|Example URL|params|
>|:--|:--|:--|
>|pages/blog/[slug].js|/blog/a|{ slug: 'a' }|
>|pages/blog/[slug].js|/blog/b|{ slug: 'b' }|
>|pages/blog/[slug].js|/blog/c|{ slug: 'c' }|
つまり、`[任意のファイル名].tsx(.jsでもOK)`とすることで、[slug].tsxという1つのファイルで`/blog/a`,`/blog/b`,`/blog/c`など様々なルートをキャッチできるということです。
加えて、その任意のファイル名をキーとして、値を取得・利用することもできます。とっても便利で簡単ですね。
しかし、私は全くうまくいきませんでした。
# 失敗例
Next.js/app/page.tsx(省略したもの)
```TypeScript
"use client"
import Link from "next/link";
import React, { useState, useEffect } from 'react';

export default function Home() {
  const [articles, setArticles] = useState(null);
    const fetchArticles = async () => {
    try {
      const res = await fetch(`APIエンドポイントを記入`)
      const data = await res.json();
      setArticles(data);

    } catch (error) {
      console.error('Error:', error);
    }

  };

  useEffect(() => {
    fetchArticles();
  }, []);

  return (
    <>
      <div className="article-preview">
        <div className="article-meta">
          <Link href="/profile/{user_name}">
            <img src="http://i.imgur.com/Qr71crq.jpg" />
          </Link>
          <div className="info">
            <Link href="/profile/{user_name}" className="author">
              {article.user.name}
            </Link>
            <span className="date">{article.created_at}</span>
          </div>
          <button className="btn btn-outline-primary btn-sm pull-xs-right">
            <i className="ion-heart" /> 29
          </button>
        </div>
        <Link
          href={`/article/${article.id}`} //問題の部分
          className="preview-link"
        >
          <h1>{article.title}</h1>
          <p>{article.summary}</p>
          <span>Read more...</span>
          <ul className="tag-list">
            <li className="tag-default tag-pill tag-outline">{article.tagList}</li>
          </ul>
        </Link>
      </div>
    </>
  );
}
```
この`<Link　href={\`/article/${article.id}\`}　className="preview-link">`で、APIから取得してきたデータIDをリンク先のURLに含めました。ここは動的に変わる部分。つまり先ほどの動的ルーティングの出番です。
わたしは以下のような構造にしました。
```
app
├　page.tsx
└　article(ディレクトリ)
　 └　[id].tsx
```
これで、`article/`以下がどうなっていても上手くいくはず。しかし、結果は404エラー。「ページあるよ！！」と思っていました。

# 解決した方法
色々調べてみたところ、失敗例のようにファイル名を`[]`にする人の他、ディレクトリ名を[]にしている人がいました。

:::note info
追記(2024.1.29)
>色々調べてみたところ、失敗例のようにファイル名を`[]`にする人の他、ディレクトリ名を[]にしている人がいました。

についてコメント頂いた内容を記載。
>Pages Router では、/pages ディレクトリ内の決まった拡張子のファイルすべてがページのコンポーネントになり得ましたが、
>App Router では、/app ディレクトリ内の各ディレクトリの中にある /page.tsx のようなファイルだけがページのコンポーネントになります。
>/app と /pages でファイル名についての規約が異なる、ということになります。

できると思っていた[〇〇].tsxは`/app`ではページコンポーネントとしてみなされず、エラーが出ていたようです。

:::

現在、Next.jsでは以下のようにルーティングがされています

https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts

```
app
├　page.tsx
└　dashboard(ディレクトリ)
　 └　page.tsx
```
`app/page.tsx`はURLでは`/`。`app/dashboard/page.tsx`はURL`/dashboard`で参照されます。そこでふと思いました。
先ほどの失敗例のように`/article/${article.id}`で接続したいなら、
```
app
├　page.tsx
└　article(ディレクトリ)
　 └　[id](ディレクトリ)
      └　page.tsx
```
にすべきではないのか？？と。上記のように変更すると、無事ページ遷移に成功しました。

# まとめ
ずっとできなかった動的ルーティング。もしかすると、他の解決方法があるかもしれません。他にも調べてできたら、追記していこうと思います。