🌊
Astro.url.pathname が本番環境で機能しない問題を解決する
環境
- Astro: 4.0.3
- Package manager: pnpm
発生した不具合
色々な Web サイトで見かける、現在の path とナビゲーションメニューの path が一致している場合にメニューをハイライト表示する実装を Astro.url.pathname
で実装していた時に起こったバグ(?)。
↓ こんなやつ( /about ページのとき )
実際のコード(CSS は省略)
Menu.astro
---
const navItems = [
{
name: "Home",
path: "/",
},
{
name: "About",
path: "/about",
},
{
name: "Staff",
path: "/staff",
},
{
name: "Job",
path: "/job",
},
{
name: "Contact",
path: "/contact",
},
];
const active = Astro.url.pathname;
---
<nav class="menu">
<ul class="list">
{
navItems.map(({ name, path }) => (
<li class="listItem">
<a href={path} class={active === path ? "active" : ""}>
{name}
</a>
</li>
))
}
</ul>
</nav>
上記のコードで開発環境では期待通りハイライト表示されたが、ビルド後に確認するとルートディレクトリにいる時だけハイライト表示され他ページではハイライト表示されなかった。
解決方法
解決法は簡単で、path の末尾に/(スラッシュ)を付けることで本番環境でも期待通りの見た目を再現することができる。
修正後のコード
Menu.astro
---
const navItems = [
{
name: "Home",
path: "/",
},
{
name: "About",
path: "/about/", // 末尾にスラッシュを追加
},
{
name: "Staff",
path: "/staff/", // 末尾にスラッシュを追加
},
{
name: "Job",
path: "/job/", // 末尾にスラッシュを追加
},
{
name: "Contact",
path: "/contact/", // 末尾にスラッシュを追加
},
];
const active = Astro.url.pathname;
---
<nav class="menu">
<ul class="list">
{
navItems.map(({ name, path }) => (
<li class="listItem">
<a href={path} class={active === path ? "active" : ""}>
{name}
</a>
</li>
))
}
</ul>
</nav>
原因
Astro は開発モード時、 URL にスラッシュがつく場合は自動的に末尾にスラッシュがつくが、本番環境ではそのスラッシュがつかないため、開発時と本番環境で 末尾の URL に差異が生じるのが原因。
以下の設定で、開発時でも URL の末尾にスラッシュがない場合はページ遷移できないようになるので、本件が解消されるまで URL の末尾にスラッシュをつける癖をつけた方が良さそう。
astro.config.mjs
import { defineConfig } from "astro/config";
// https://astro.build/config
export default defineConfig({
trailingSlash: "always",
});
※関連 Issue
Discussion