~ 4 min read
Component auto import in Astro framework
The Astro frontend framework is such a delight to work with but I was missing a feature with regards to islands and framework components that allowed the page data, such as blog posts, to automatically import the components that are used in the markdown file. This is how I solved it.
About MDX and Astro
Astro is a frontend framework that allows you to build websites, like a personal blog, using a mix of static and dynamic content. It’s a great way to build websites that are fast, optimized for SEO due to the server-side rendering and server-generated pages support, and easy to maintain.
One of the features of Astro is that it allows you to use MDX files to create pages. MDX is a way to write JSX in markdown files. This allows you to extend the Markdown syntax and use framework components in your markdown files to create rich content. MDX is well-supported in Astro using the @astro/mdx
package and the MDX syntax is built on-top of Markdown so you don’t really need to learn a new syntax and can maintain the frontmatter and markdown syntax that you are already familiar with.
Her’es an example of MDX files:
---
title: "Hello, world!"
date: "2024-06-06"
---
import SomeComponent from './SomeComponent.jsx';
# Hello, world!
<SomeComponent prop="propValue" />
This is a blog post written in MDX, <Button name="Click me" />.
The rendered page will have the SomeComponent
and Button
components rendered in the page content but will not show the import SomeComponent ...
statement. This is because the @astro/mdx
package processes the MDX file and injects the component imports into the page. Of course, don’t forget saving this file with an .mdx
extension: blog-hello-world.mdx
.
Auto import components in Astro
If you search “astro framework component auto import” long enough you’ll land on the community contributed Astro package called astro-auto-import by the splendid Chris Swithinbank.
In essence, the astro-auto-import
package reads the component file from the path that you specify in the Astro integration configuration file and then generates the appropriate ESM module tree for it that gets injected into the markdown imports and looks something like this:
return {
type: 'mdxjsEsm',
value: '',
data: {
estree: {
body: [],
...parseJs(js, { ecmaVersion: 'latest', sourceType: 'module' }),
type: 'Program',
sourceType: 'module',
},
},
};
Benefits of using astro-auto-import
:
- You can import React, Vue, and other framework components.
- You don’t need to explicitly and manually import the components in the markdown file.
- You can maintain both
.md
and.mdx
files side by side in your Astro blog.
Configure the Astro Auto Import integration by adding the following to your astro.config.mjs
file:
// .. other imports
import AutoImport from 'astro-auto-import';
export default defineConfig({
// ... other config options
integrations: [
// The Auto Import configuration here:
AutoImport({
imports: ['./src/components/widgets/BlogCallToAction.vue'],
}),
// Make sure that the mdx() integration is *after* the Auto Import integration
// *AND IMPORTANT* to make sure that the mdx integration doesn't repeat any prior markdown configured
// plugins like remarkToc or remarkReadingTime
mdx(),
],
markdown: {
remarkPlugins: [remarkToc, remarkReadingTime],
extendDefaultPlugins: true,
},
});
The following are especially important to note:
- The
imports
array in theAutoImport
configuration should contain the path to the components that you want to auto-import in the markdown files. - The
mdx()
integration should be placed after theAutoImport
integration in theintegrations
array. - The
mdx()
integration should not repeat any prior markdown configured plugins likeremarkToc
orremarkReadingTime
.
If you skip the last one and you have some markdown plugins stated in the mdx() integration, you will get an error like this:
[Vue warn]: Component <Anonymous> is missing template or render function.
[Vue warn]: Component <Anonymous> is missing template or render function.
error Could not render `[object Module]`. No matching import has been found for `[object Module]`.
Hint:
Please make sure the component is properly imported.
Error reference:
or some other Vite error similar to the above which states that it can’t find the component that you are trying to render in the MDX file and the whole page won’t load. Astro will crash.
Once everything is installed and setup, just use the component in your MDX files without having to declare the import statement:
# Hello, world!
<SomeComponent prop="propValue" />
This is a blog post written in MDX, <Button name="Click me" />.
No more manual imports, kind of like using globals in Markdown files 😅 but hey, at least those Markdown files are portable and consistent and won’t have a weird import
looking statement in the beginning of the file when you migrate or import them to a new system next time!