Skip to contentView the source on GitHub

prefer-content-collections

Prefer Content Collections over Astro.glob() or import.meta.glob() for Markdown and MDX files.

Best Practiceswarning by default ESLint rule

astro-doctor/prefer-content-collections

Why it matters

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.

See the difference

Incorrect

Using Astro.glob()

astroIncorrect example
---
// 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

astroCorrect example
---
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>

Configure this check

Override the default severity in your ESLint config:

javascripteslint.config.js
import astroDoctorPlugin from '@santi020k/eslint-plugin-astro-doctor'

export default [
  astroDoctorPlugin.configs.recommended,
  {
    rules: {
      'astro-doctor/prefer-content-collections': 'error',
    },
  },
]

Or set the severity for CLI scans in doctor.config.ts:

typescriptdoctor.config.ts
export default {
  rules: {
    'astro-doctor/prefer-content-collections': 'error',
  },
}

Use 'error', 'warn', or 'off'. The configuration guide covers presets and per-file overrides.

Keep exploring best practices

Browse every rule and project audit