1
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Next.js 9.5のアップデートにより、GitHub Pagesで妥協しない動的ルーティングが可能になった

Posted at

Qiita: Next.jsで作ったアプリをGitHub Pagesにデプロイする@ozaki25』や、『Qiita: Next.jsをGitHub Pagesにデプロイしたらリンクが壊れた』、『GitHub: gh-pages Hello World example』にNext.jsのWebサイトをGithub Pagesに投稿する方法が載っていますが、どれも静的ページのみへのルーティングを説明していて、動的ルーティングには深く言及されていません。

そこで、Next.js 9.4でサイトをGitHub Pagesにあげたところ、動的ルーティングでハマってしまいました。結果、対処法がわからずにVercelに移行したのですが、Next.js 9.5のアップデートベースパスをカスタマイズできる機能が追加され、自分がハマっていた動的ルーティングが解決しました!🎉

この記事では、Next.js 9.4の動的ルーティングのハマっていた背景とNext.js 9.5での対処法について説明します。

Next.js 9.4 × GitHub Pages 🤔

ご存知だと思いますが、GitHub Pagesはhttps://[username].github.io/[repository-name]といったurlにマッピングされます。これによって、以下のような普通のNext.jsのルーティングでは、https://[username].github.io/[repository-name]/itemsに行ってほしいのに、https://[username].github.io/itemsにルーティングされてしまい、リロード時にエラーとなってしまいます。

MyLink.tsx
const MyLink = () => (
  <Link href="/items">
    <a>Item</a>
  </Link>
)

なので、『Qiita: Next.jsをGitHub Pagesにデプロイしたらリンクが壊れた』などに記載されている変更が必要となります。

next.config.js
module.exports = {
  assetPrefix: process.env.NODE_ENV === 'production' ? '/[repository-name]' : ''
}
MyLink.tsx
const withRootPath = (path: string) =>
  process.env.NODE_ENV === 'production' ? `/[repository-name]/${path}` : path

const MyLink = () => (
  <Link href={withRootPath("/items")}>
    <a>Item</a>
  </Link>
)

これで、静的なリンクへはうまくいきます。が、前述している通り、動的ルーティングの場合は同様に以下のようにしてもプリフェッチされず、ブラウザのロードが挟まれてしまいます。

MyLink.tsx
const withRootPath = (path: string) =>
  process.env.NODE_ENV === 'production' ? `/[repository-name]/${path}` : path

const MyLink = () => (
  <Link href={withRootPath("/items")}>
    <a>Item</a>
  </Link>
)
const MyDynamicLink = () => (
  <Link href={withRootPath("/items/[id]")} as={withRootPath("/items/a")}>
    <a>Item</a>
  </Link>
)

また、上の記事に記載されている以下の方法で実装すると、エラーを出力します。

MyLink.tsx(差分)
const MyDynamicLink = () => (
  <Link href="/items/[id]" as={withRootPath("/items/a")}>
    <a>Item</a>
  </Link>
)
error.PNG

これは、hrefasが対応していない事によるエラーです。詳しい内容はNext.jsのリポジトリに記入してあります。vercel/next.js-Incompatible href and as values

…ということで、自分の知る限りではGitHubでNext.jsの動的ルーティングを実装するには、プリフェッチとブラウザへのロードを妥協するしかありませんでした。

Next.js 9.5 × GitHub Pages 🎉

最初に説明している通り、Next.js 9.5でベースパスを設定できるようになりました。対処法も簡単で、next.config.jsに追加するだけでOKです。

next.config.js
module.exports = {
  basePath: process.env.NODE_ENV === 'production' ? '/[repository-name]' : ''
}

これだけで、妥協しない動的ルーティングが可能になります🎉

おわりに

自分の認識不足で、Next.js 9.4でも動的ルーティングでプリフェッチできる方法がありましたら、教えてください。

デモとして使用したリポジトリ

1
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?