概要
Astroでconfigにbase
を設定しつつリダイレクトを設定したときの挙動が、パッとドキュメントを見たときに想像したものと違ったので、備忘録を兼ねて記事にしました。
初見ではハマってしまいそうな挙動とその解決策についてまとめています。
対象読者
- Astroでサブディレクトリにサイトをデプロイする方
-
base
設定とredirects
を同時に使用する方
結論
Astroでbase
を設定した場合、redirects
のリダイレクト先にはbase
パスが自動的に付与されないため、明示的に含める必要があります。
環境
この記事を書くにあたり手元で検証した際のバージョンです。
依存関係 | バージョン |
---|---|
astro | 5.13.5 |
前提知識:Astroのconfigにおけるbase
以下のようにbase
を設定した場合、サイトのトップが開発環境ではlocalhost:4321/docs
になり、本番環境ではhttps://example.com/docs
になります。
import { defineConfig } from "astro/config";
export default defineConfig({
+ base: '/docs'
});
参照:
前提知識:Astroでリダイレクトを設定する方法
公式ドキュメントのサンプルコードを拝借して説明します。
astro.config.mjs
にredirect
を追加し、リダイレクト元とリダイレクト先を設定するだけです。
外部URLへのリダイレクトもできます。
import { defineConfig } from "astro/config";
export default defineConfig({
+ redirects: {
+ "/old-page": "/new-page",
+ "/blog": "https://example.com/blog"
+ }
});
参照:
base
を設定しつつサンプルと同様にリダイレクト先を設定したときの挙動
前提知識
のセクションの内容を2つとも適用して、このようなconfigファイルを設定したとします。
import { defineConfig } from "astro/config";
export default defineConfig({
+ base: '/docs',
+ redirects: {
+ "/old-page": "/new-page"
+ }
});
new-page
を開く為には、開発環境でいうとlocalhost:4321/docs/new-page
を叩く必要があります。
ここでlocalhost:4321/docs/old-page
を叩いた際はlocalhost:4321/docs/new-page
にリダイレクトすることを期待しますよね?
しかし、そうは動きません。
実際にリダイレクトされる先はlocalhost:4321/new-page
で、404になってしまいます。
これは本番環境であっても同じ挙動です。
期待する通り/docs/new-page
にリダイレクトさせるためには、次のようにconfigファイルを書く必要があります。
import { defineConfig } from "astro/config";
export default defineConfig({
base: '/docs',
redirects: {
- "/old-page": "/new-page"
+ "/old-page": "/docs/new-page"
}
});
もちろん次のように書いても同様に動作します。
import { defineConfig } from "astro/config";
+ const basePath = '/docs'
export default defineConfig({
- base: '/docs',
+ base: basePath,
redirects: {
- "/old-page": "/new-page"
+ "/old-page": `${basePath}/new-page`
}
});
補足:外部URLへのリダイレクトについて
なお、当然と言えば当然ですが外部URLへリダイレクトする際はbase
の影響は受けません。
純粋にリダイレクトしたいURLを記載するだけでOKです。
import { defineConfig } from "astro/config";
export default defineConfig({
base: '/docs',
redirects: {
"/old-page": "/docs/new-page",
"/blog": "https://example.com/blog"
}
});
補足:Astroがリダイレクト先を設定している方法
npx build
するとdist
の中にHTMLファイルが生成されます。
その際http-equiv属性が設定されてリダイレクトが走ります。
ただ、ビルド処理のうちリダイレクトに関係する処理ではbase
は使われておらず、redirect
の中身だけが使われているため、今回記事にしたような挙動が起きているようです。
参考程度ですがredirects: { "/old-page": "/new-page" }
として設定した場合、/old-page
は次のように出力されます。
<!doctype html>
<title>Redirecting to: /new-page</title>
<meta http-equiv="refresh" content="0;url=/new-page">
<meta name="robots" content="noindex">
<link rel="canonical" href="/new-page">
<body>
<a href="/new-page">Redirecting from
<code>/docs/old-page/</code> to <code>/new-page</code>
</a>
</body>
redirects: { "/old-page": "/docs/new-page" }
として設定した場合は次のようになります。
<!doctype html>
<title>Redirecting to: /docs/new-page</title>
<meta http-equiv="refresh" content="0;url=/docs/new-page">
<meta name="robots" content="noindex">
<link rel="canonical" href="/docs/new-page">
<body>
<a href="/docs/new-page">Redirecting from
<code>/docs/old-page/</code> to <code>/docs/new-page</code>
</a>
</body>
なお、読みやすくするためにフォーマットして記載していますが、実際は1行で出力されています。
まとめ
-
redirects
設定はbase
の値を考慮しないため、手動でパスを調整する必要がある - リダイレクト先が多い場合などは
base
を変数化して管理した方が良い - ただし外部URLへのリダイレクトは
base
の影響を受けない