1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Astroでbaseを設定したらリダイレクトが404エラーになるときの対処法

Posted at

概要

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になります。

astro.config.mjs
  import { defineConfig } from "astro/config";

  export default defineConfig({
+   base: '/docs'
  });

参照:

前提知識:Astroでリダイレクトを設定する方法

公式ドキュメントのサンプルコードを拝借して説明します。

astro.config.mjsredirectを追加し、リダイレクト元とリダイレクト先を設定するだけです。
外部URLへのリダイレクトもできます。

astro.config.mjs
  import { defineConfig } from "astro/config";

  export default defineConfig({
+   redirects: {
+     "/old-page": "/new-page",
+     "/blog": "https://example.com/blog"
+   }
  });

参照:

baseを設定しつつサンプルと同様にリダイレクト先を設定したときの挙動

前提知識のセクションの内容を2つとも適用して、このようなconfigファイルを設定したとします。

astro.config.mjs
  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ファイルを書く必要があります。

astro.config.mjs
  import { defineConfig } from "astro/config";

  export default defineConfig({
    base: '/docs',
    redirects: {
-     "/old-page": "/new-page"
+     "/old-page": "/docs/new-page"
    }
  });

もちろん次のように書いても同様に動作します。

astro.config.mjs
  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です。

astro.config.mjs
  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は次のように出力されます。

dist/old-page/index.html
<!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" }として設定した場合は次のようになります。

dist/old-page/index.html
<!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の影響を受けない
1
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?