Next.jsのrouter周りのバグ


動作バージョン: Next.js v9.5.5
Next.jsのルーティング周りはまだあまり安定していなくて、2点ほど困ったことが起きていたのでその事象と
回避策を記します。

SSR時の初期表示時にqueryがundefinedになる

/mypage?tab=profile のようなリンクで、初期表示時に表示するタブを切り替えるなどを行いたくて、以下のようなコードを書いていました。

const Mypage: NextPage = () => {
  const router = useRouter();
  const [selectedTab, setSelectedTab] = useState("message");
  useEffect(() => {
    const tab = ["profile", "message", "support"].find((t) => t === router.query.tab) || "message";
    setSelectedTab(tab);
  }, [router.query.tab]);
  return (
    <div>
      ...
    </div>
  );
}

このような記述のコードを書いていたら、初回表示時のみqueryがundefinedになってしまいました。
どうもこれは公式でも認知しているバグのようですが、これでは困ります。

https://github.com/vercel/next.js/discussions/11484

回避策

初期表示時でも router.asPath の値は正常に取得できるということが分かったので、 query-string を使用して、urlから直接参照するという方式にしました。
そのコードが次です。

const Mypage: NextPage = () => {
  const router = useRouter();
  const [selectedTab, setSelectedTab] = useState("message");
  useEffect(() => {
    const dist = queryString.parse(router.asPath.split(/\?/)[1])["tab"] as string;
    const tab = ["profile", "message", "support"].find((t) => t === dist) || "message";
    setSelectedTab(tab);
  }, [router.asPath]);
  return (
    <div>
      ...
    </div>
  );
}

APIモードにリダイレクトモードを使用したらqueryがundefinedになった

これもqueryの問題です。9.5.5で導入されたrewriteモードを使用して、apiのpathを変更したら、queryがundefinedになってしまいました。
これに対する公式のissueは見つけられませんでした。

回避策

queryに指定したかったパラメータが1つだけだったので、個人的にはやりたくなかったのですが、urlに含めるという対応を行ったところ、問題なくリダイレクトされて使用できました。

next.js.config
async rewrites() {
    return [
      {
-        source: "/client/api/address",
-        destination: "/api/address",
+        source: "/client/api/address/:zipcode",
+        destination: "/api/address/:zipcode",
      },
    ];
  },

Next.jsは個人的に今最も推しているフレームワークでありますが、その活発さに相まって不具合が多く見つかってしまうので、公式のissue/discussionをよく読むようにしたいです。