What Causes This Error?
This error occurs when two different routes in your Astro project generate the same output path. Each page must have a unique URL path.
The Problem
src/pages/
├── blog.astro # Generates /blog
└── blog/
└── index.astro # Also generates /blog ❌ Conflict!
---
// src/pages/[slug].astro
export function getStaticPaths() {
return [
{ params: { slug: 'about' } }, // Generates /about
];
}
---
// src/pages/about.astro also exists! ❌ Conflict!
The Fix
Remove Duplicate Routes
src/pages/
├── blog/
│ └── index.astro # ✅ Only one generates /blog
Rename Conflicting Files
src/pages/
├── blog-page.astro # Generates /blog-page
└── blog/
└── index.astro # Generates /blog ✅ No conflict
Exclude From Dynamic Route
---
// src/pages/[slug].astro
export function getStaticPaths() {
const pages = await getPages();
// ✅ Filter out slugs that conflict with static pages
const staticPages = ['about', 'contact', 'blog'];
return pages
.filter((page) => !staticPages.includes(page.slug))
.map((page) => ({
params: { slug: page.slug },
}));
}
---
Common Scenarios
Index Page Conflicts
# ❌ Both generate /products
src/pages/products.astro
src/pages/products/index.astro
# ✅ Choose one
src/pages/products/index.astro # Use this for /products
Dynamic and Static Overlap
---
// src/pages/posts/[slug].astro
// If you also have src/pages/posts/featured.astro
export function getStaticPaths() {
const posts = await getPosts();
// ❌ If a post has slug 'featured', it conflicts
return posts.map((post) => ({
params: { slug: post.slug },
}));
}
// ✅ Exclude reserved slugs
export function getStaticPaths() {
const posts = await getPosts();
const reserved = ['featured', 'archive', 'tags'];
return posts
.filter((post) => !reserved.includes(post.slug))
.map((post) => ({
params: { slug: post.slug },
}));
}
---
Trailing Slash Issues
// astro.config.mjs
export default defineConfig({
trailingSlash: 'always', // or 'never' or 'ignore'
});
# With trailingSlash: 'always'
/blog/ and /blog are different
But both generate the same file!
Rest Parameters Catch-All
---
// src/pages/[...path].astro
export function getStaticPaths() {
return [
{ params: { path: undefined } }, // Generates /
{ params: { path: 'about' } }, // Conflicts if /about.astro exists
];
}
// ✅ Be specific with catch-all routes
export function getStaticPaths() {
return [
{ params: { path: 'docs' } },
{ params: { path: 'docs/intro' } },
{ params: { path: 'docs/api' } },
];
}
---
Localized Routes
---
// src/pages/[lang]/about.astro
export function getStaticPaths() {
return [
{ params: { lang: 'en' } }, // /en/about
{ params: { lang: '' } }, // /about - might conflict!
];
}
// ✅ Use explicit language codes
export function getStaticPaths() {
return [
{ params: { lang: 'en' } },
{ params: { lang: 'es' } },
];
}
---
Quick Checklist
- Check for duplicate files generating same path
- Use
index.astroORname.astro, not both - Filter reserved slugs from dynamic routes
- Be careful with rest parameters
[...path] - Check
trailingSlashconfiguration