javascriptslugastrojs

Import .md files dynamically by slug


i am pretty new to Astro, and i want to find out how to have a file such as [...slug] read md files based on that slug. Best with using collection entries or something similar. It seems there is no easy way because Javascript does not know how to import them first.

Almost everything possible in the documentation.


Solution

  • You can leverage collections along with dynamic routes. Create a collection to store your markdown files. For instance, you can create a directory src/content/posts and add markdown files with frontmatter for metadata, like src/content/posts/first-post.md with the following content:

    ---
    title: "First Post"
    date: "2023-07-15"
    ---
    
    # first Post
    
    This is the content of the first post.
    

    Next, configure Astro to recognize and read these markdown files. Create a collection config file, such as src/content/config.ts, and define your collection:

    import { defineCollection, z } from 'astro:content';
    
    const posts = defineCollection({
      schema: z.object({
        title: z.string(),
        date: z.string().transform((str) => new Date(str)),
      }),
    });
    
    export const collections = {
      posts,
    };
    

    Update your astro.config.mjs to include the content module:

    import { defineConfig } from 'astro/config';
    import content from '@astro/content';
    
    export default defineConfig({
      integrations: [content()],
    });
    

    Now, create a dynamic route to serve the markdown content based on the slug. Create a file src/pages/posts/[...slug].astro:

    ---
    // Import necessary utilities and components
    import { getEntryBySlug } from 'astro:content';
    import { Markdown } from '@astro/components';
    
    // Get the slug from the URL
    const { slug } = Astro.url;
    const post = await getEntryBySlug('posts', slug);
    
    // If post is not found, show a 404 page
    if (!post) {
      throw Astro.error(404, `Post ${slug} not found`);
    }
    ---
    
    <Markdown content={post.body} />
    

    In the dynamic route file [...slug].astro, use the Markdown component to render the content of the markdown file. The getEntryBySlug function retrieves the markdown content based on the slug, and the Markdown component renders the markdown content.

    This setup ensures you can dynamically read and display markdown files in your Astro project based on the URL slug. It involves creating a collection directory for markdown files, configuring Astro to read the collection, creating a dynamic route to serve content based on the slug, and using the Markdown component to render the markdown content. This approach provides a structured and flexible way to manage and display markdown content in your Astro project.