Best Practices warn by default
astro-doctor/prefer-content-collections prefer-content-collections
Prefer Content Collections over Astro.glob() or import.meta.glob() for Markdown and MDX files.
Why
Astro.glob() and import.meta.glob() return untyped content objects. Content Collections provide TypeScript types via the schema you define, build-time validation that catches typos and missing fields before deploy, and caching for better performance. They are the recommended approach for structured content.
Examples
✗ Incorrect
Using Astro.glob()
---
// No types, no validation, runs every request
const posts = await Astro.glob('../content/blog/*.md')
---
<ul>
{posts.map(post => (
<li>{post.frontmatter.title}</li>
))}
</ul> ✓ Correct
Using Content Collections
---
import { getCollection } from 'astro:content'
// Typed, validated at build time, cached
const posts = await getCollection('blog', ({ data }) => !data.draft)
---
<ul>
{posts.map(post => (
<li>{post.data.title}</li>
))}
</ul> Configuration
Override the default severity in your ESLint config:
// eslint.config.js
import astroDoctorPlugin from '@santi020k/eslint-plugin-astro-doctor'
export default [
astroDoctorPlugin.configs.recommended,
{
rules: {
'astro-doctor/prefer-content-collections': 'error', // or 'warn' or 'off'
},
},
]
Or in your doctor.config.ts:
export default {
rules: {
'astro-doctor/prefer-content-collections': 'error',
},
}
All rules
-
astro-doctor/no-client-load-overuse -
astro-doctor/use-astro-image -
astro-doctor/require-image-dimensions -
astro-doctor/no-missing-alt -
astro-doctor/no-set-html -
astro-doctor/no-public-secret-env -
astro-doctor/prefer-class-list -
astro-doctor/no-blocking-script -
astro-doctor/no-unprocessed-script-surprises -
astro-doctor/no-missing-lang -
astro-doctor/require-island-fallback -
astro-doctor/no-process-env -
astro-doctor/prefer-content-collections(this page)