NNicheStackTutorials
← All tutorials
Astro

Astro Redirect Rules for Static Hosting (_redirects + astro.config)

301 redirects from old URLs, trailing slash normalization, and when to use redirects vs getStaticPaths.

·11 min read·Astro
Astro Redirect Rules for Static Hosting (_redirects + astro.config) cover

Tested on: Astro 5.7, Netlify + Cloudflare Pages Scenario: Migrated from /posts/slug to /blog/slug. 40 old URLs needed 301s.

Option 1 — hosting _redirects (my choice)

public/_redirects:

/posts/*        /blog/:splat    301
/writing        /blog/          301
/rss.xml        /blog/rss.xml   301
/old-about      /about/         301

Works on Netlify and Cloudflare Pages. Files copy to dist/_redirects on build.

Option 2 — astro.config redirects (build-time)

export default defineConfig({
  redirects: {
    '/posts/[...slug]': '/blog/[...slug]',
    '/writing': '/blog'
  }
});

Astro generates HTML meta-refresh or hosting-specific files depending on adapter.

For pure static (no adapter), redirects in config creates HTML redirect pages — works but slower than server 301.

Option 3 — getStaticPaths alias (content migration)

Temporary dual URLs during transition:

---
// src/pages/posts/[slug].astro
import { getCollection } from 'astro:content';

export async function getStaticPaths() {
  const posts = await getCollection('blog');
  return posts.map((p) => ({
    params: { slug: p.slug },
    props: { redirect: `/blog/${p.slug}/` }
  }));
}

const { redirect } = Astro.props;
---

<meta http-equiv="refresh" content={`0;url=${redirect}`} />
<link rel="canonical" href={redirect} />

Prefer 301 via _redirects for SEO. Meta refresh is fallback.

Trailing slash normalization

astro.config.mjs:

export default defineConfig({
  trailingSlash: 'always' // or 'never' — pick one
});

_redirects complement:

/blog          /blog/          301
/about         /about/         301

Error — redirect loop

/blog/  /blog  301
/blog   /blog/ 301

Pick one trailing slash style. Two rules fighting = infinite loop.

Cloudflare _redirects syntax difference

Cloudflare supports:

/posts/:slug  /blog/:slug  301

Netlify uses :splat for wildcards. Test on your host.

Verify all 40 redirects

scripts/check-redirects.mjs:

const rules = [
  ['/posts/hello-world', '/blog/hello-world'],
  ['/writing', '/blog']
];

const base = 'https://myblog.dev';

for (const [from, expectedLocation] of rules) {
  const res = await fetch(`${base}${from}`, { redirect: 'manual' });
  const loc = res.headers.get('location');
  console.log(from, res.status, loc === expectedLocation || loc === expectedLocation + '/' ? 'OK' : `FAIL: ${loc}`);
}

Google Search Console

After deploy, submit updated sitemap. Old URLs show "Page with redirect" — expected. Rankings transfer in 2-4 weeks.

Result

40 redirects deployed via _redirects
0 redirect loops
Build time impact: 0s (hosting-level)
GSC crawl errors: 38 → 0 in 10 days

Tags: AstroRedirectsStatic HostingSEO