What Causes This Error?
This error occurs when you use Astro.glob() in a file that isn’t an .astro file. The Astro global object is only available in .astro components.
The Problem
// src/utils/getPosts.js
// ❌ Astro.glob not available in .js files
export async function getPosts() {
return await Astro.glob('../content/blog/*.md');
}
// src/lib/content.ts
// ❌ Astro.glob not available in .ts files
const posts = await Astro.glob('./posts/*.md');
The Fix
Use import.meta.glob Instead
// src/utils/getPosts.js
// ✅ import.meta.glob works in any file
export async function getPosts() {
const posts = import.meta.glob('../content/blog/*.md', { eager: true });
return Object.values(posts);
}
Or Use Content Collections
// src/utils/getPosts.ts
import { getCollection } from 'astro:content';
// ✅ Content collections work anywhere
export async function getPosts() {
return await getCollection('blog');
}
Common Scenarios
Helper Functions
// src/utils/content.js
// ❌ Won't work
export async function getAllPosts() {
return await Astro.glob('../posts/*.md');
}
// ✅ Works - use import.meta.glob
export function getAllPosts() {
const posts = import.meta.glob('../posts/*.md', { eager: true });
return Object.values(posts).map(post => post.default);
}
In JavaScript/TypeScript Files
// src/lib/images.ts
// ❌ Astro object not available
const images = await Astro.glob('../assets/*.jpg');
// ✅ Use import.meta.glob
const imageModules = import.meta.glob('../assets/*.jpg', {
eager: true,
query: '?url',
import: 'default',
});
export const images = Object.values(imageModules);
Use in .astro Files
---
// src/pages/blog/index.astro
// ✅ Astro.glob works in .astro files
const posts = await Astro.glob('../content/blog/*.md');
---
{posts.map(post => (
<article>
<h2>{post.frontmatter.title}</h2>
</article>
))}
Passing Glob Results as Props
---
// src/pages/index.astro
// Glob in .astro file
const posts = await Astro.glob('./posts/*.md');
---
<!-- Pass to components -->
<PostList posts={posts} />
---
// src/components/PostList.astro
// Receive as props instead of globbing
const { posts } = Astro.props;
---
<ul>
{posts.map(post => <li>{post.frontmatter.title}</li>)}
</ul>
import.meta.glob Options
// Non-eager (lazy loading)
const modules = import.meta.glob('./posts/*.md');
// Returns { './posts/a.md': () => import('./posts/a.md') }
// Eager (immediate loading)
const modules = import.meta.glob('./posts/*.md', { eager: true });
// Returns { './posts/a.md': { default: ..., frontmatter: ... } }
// Import specific export
const modules = import.meta.glob('./posts/*.md', {
import: 'frontmatter',
eager: true,
});
Content Collections (Recommended)
// src/content/config.ts
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
date: z.date(),
}),
});
export const collections = { blog };
// src/utils/posts.ts
import { getCollection } from 'astro:content';
// ✅ Works anywhere
export async function getBlogPosts() {
return await getCollection('blog');
}
Comparison
| Feature | Astro.glob() | import.meta.glob | Content Collections |
|---|---|---|---|
| Works in .astro | ✅ | ✅ | ✅ |
| Works in .js/.ts | ❌ | ✅ | ✅ |
| Type safety | ❌ | ❌ | ✅ |
| Schema validation | ❌ | ❌ | ✅ |
| Recommended | Legacy | For assets | For content |
Quick Checklist
-
Astro.glob()only works in.astrofiles - Use
import.meta.glob()in JS/TS files - Use Content Collections for typed content
- Pass glob results as props to components
- Consider migrating from Astro.glob to Content Collections