Astro.glob errors, such as “Astro.glob() used outside of an Astro file” or Astro.glob is not a function after upgrading, all have the same fix: stop using Astro.glob(). It was deprecated and then removed from current Astro versions. Astro’s own message points to the replacement: “import.meta.glob() can be used instead to achieve a similar result.” For Markdown content, a content collection with getCollection() is the better long-term replacement.
Key Takeaways
Astro.glob()no longer exists in current Astro.- Files of any kind: use Vite’s
import.meta.glob()(add{ eager: true }for the closest behaviour).- Markdown and MDX content: define a collection and use
getCollection().import.meta.glob()patterns must be string literals.
Replacement 1: import.meta.glob()
---
- const posts = await Astro.glob('../posts/*.md');
+ const posts = Object.values(import.meta.glob('../posts/*.md', { eager: true }));
---
Astro.glob() returned an array of modules; import.meta.glob() returns an object keyed by path, hence Object.values(). Each module still has frontmatter, url and Content for Markdown files.
Without eager, you get functions to call:
const modules = import.meta.glob('../posts/*.md');
const posts = await Promise.all(Object.values(modules).map((load) => load()));
It also works outside .astro files, which is the case the original error message describes: Astro.glob() only ever worked inside Astro components.
Replacement 2: content collections
For Markdown and MDX you render as pages, a collection gives you validation, types and ids:
// src/content.config.ts
const posts = defineCollection({
loader: glob({ pattern: '*.md', base: './src/posts' }),
schema: z.object({ title: z.string(), pubDate: z.coerce.date() }),
});
export const collections = { posts };
---
import { getCollection } from 'astro:content';
const posts = await getCollection('posts');
---
{posts.map((p) => <a href={`/posts/${p.id}/`}>{p.data.title}</a>)}
Fields move from post.frontmatter.title to post.data.title. The Astro content collections guide covers setup.
Replacement 3: images
import type { ImageMetadata } from 'astro';
const images = import.meta.glob<{ default: ImageMetadata }>('../assets/gallery/*.{jpg,png}', { eager: true });
const gallery = Object.values(images).map((m) => m.default);
Pass each item to <Image src={...} />. See Local images must be imported for the pattern with dynamic lookups.
“did not match any files”
If you had the related error about no matches, the pattern is relative to the current file and must be a literal string. A variable in the pattern won’t work, because Vite resolves it at build time.
For other upgrade errors, see Legacy content config file found. Vite’s glob import docs cover options like query and import.
FAQ
Is import.meta.glob() slower than Astro.glob()?
No. Astro.glob() was a wrapper around import.meta.glob().
Should I convert everything to collections?
For content you render as pages, yes. For miscellaneous files like icons or data modules, import.meta.glob() is fine.