#Global Markdown Custom Components

1 messages · Page 1 of 1 (latest)

tulip void
#

Hello there I'm trying to solve a problem with my marked down custom components. I have a large number of markdown files as they were previously used in the Gatsby project. I would rather not have to include all of the custom components in every markdown file. I have been given to understand that you can pass custom components via the astro.config.mjs which will make them globally available to the markdown passer. Here is an example of my astro.config.mjs where I am trying to pass a component to handle introductions.

import { defineConfig } from 'astro/config';
import BlockIntroduction from '../src/components/BlockIntroduction/BlockIntroduction.astro'

// https://astro.build/config
export default defineConfig({
    // Other configurations...
    markdown: {
        render: [
        ['@astrojs/markdown-remark', {
            components: {
                'block-introduction': BlockIntroduction
            },
        }],
      ],
    },
});

The component looks like this:

---
// BlockIntroduction.astro
import style from './BlockIntroduction.module.sass'
---
<div data-testid="BlockIntroduction">
    <h1>INTRODUCTION</h1>
    <slot />
</div>

However I am getting the following error:

12:29:04 [ERROR] [config] Failed to parse source for import analysis because the content contains invalid JS syntax. If you are using JSX, make sure to name the file with the .jsx or .tsx extension.
  Stack trace:

Any help would be very much appreciated.

hoary ocean
tulip void
#

Ahh... I was wondering why I couldn't see it. Is there another way to achieve my goal; Or is the only way to use custom components like this to include the components in every markdown file.

hoary ocean
tulip void
#

I tried using this pattern for custom tags but it didn't seem to work:

#
---
import { getCollection } from 'astro:content';

import { Heading, Link } from '@/components';

export async function getStaticPaths() {
  const posts = await getCollection('blog');

  return posts.map(post => ({
    props: {
      post,
    }
  }));
}

const { post } = Astro.props;
const { Content } = await post.render();
---

<Content
  components={{
    h1: Heading,
    a: Link,
  }}
/>
#

will try again

hoary ocean
#

What is the file type of your posts? if it's .md, that's expected. If that's .mdx then you probably messed up somewhere

tulip void
#

Can I use .mdx in my content directory?

hoary ocean
#

sure! You'll need to install an integration but thats pretty much it

tulip void
#

I have "<@&1055234544183287879>/mdx": "^2.0.1" installed, I renamed my .md file .mdx and its now not showing up in the collection

#

@hoary ocean - I am so sorry to be such a pain lol, thank you so much for you patience.

hoary ocean
#

ahah no worries let me check

#

so running on latest mdx integration that's great

#

then you did convert all your entries from your article collection to .mdx?

tulip void
#

Nope, only one of them. Do the all need to be the same file type?

hoary ocean
#

I'm not sure but it may be the case

tulip void
#

let me get rid of all the others for now; and see what happens.

#
Unsupported file type article/blog/a-fork-in-the-road-ahead/index.mdx
#

oh wait

hoary ocean
tulip void
#

LOL

#

Funny you should say that...

#

Nope; I think I might need some sleep.

#

OK so still no joy with the custom component

hoary ocean
tulip void
#
---
import MasterLayout from '../../layouts/master/Layout.astro'
import { type CollectionEntry, getCollection } from 'astro:content'
import style from './article.module.sass'
import BlockIntroduction from '../../components/BlockIntroduction/BlockIntroduction.astro'

export async function getStaticPaths() {
    const posts = await getCollection('article')
    return posts.map(post => ({
        params: { slug: post.slug },
        props: post
    }))
}

type Props = CollectionEntry<'article'>
const post = Astro.props
const { Content } = await post.render()
---

<MasterLayout title={post.data.title + ' - Blog'}>
    <article class={style.article}>
        <header>
            <h1>{post.data.title}</h1>
        </header>
        <Content components={{ 'block-introduction': BlockIntroduction }} />
    </article>
</MasterLayout>
hoary ocean
#

and then how are you using it in your mdx file?

tulip void
#
<block-introduction>

Copy 

</block-introduction>
hoary ocean
#

I'm not 100% sure this syntax is supposed to work. Can you try the following instead?

<Content components={{ BlockIntroduction }} />
<BlockIntroduction>

Copy 

</BlockIntroduction>
tulip void
#

oohhh

#

interesting

hoary ocean
#

eventually it's just some jsx so jsx does not support the "vue component style" syntax with kebab-case

tulip void
#

HA!

#

@hoary ocean You are a legend!

#

Makes sense

hoary ocean
#

ahah I'm glad I could help! Maybe it's possible to use the kebab-case syntax but I have no idea how! I'd say it's reserved to regular html tags and web-components

tulip void
#

Yeah, in gatsby there was some magic component mapping thing.. but this is workable.

hoary ocean
#

Still I will ask in dev, I'm curious

tulip void
#

Cool man... are you an Astro maintainer?

hoary ocean
#

Yep!

#

But more on the support side, I keep learning just like you houston_happy

tulip void
#

Well I really appreciate it sir. Thank you.

hoary ocean
#

You're welcome! It looks like the kebab-case syntax is not supported in MDX. It was probably some gatsby magic in md files

tulip void
#

indeed. Thanks for looking

hoary ocean
#

Have a nice day and feel free to post more threads in #1019713903481081876 if you ever need help houston_happy

tulip void
#

Thank you, you too. And Merry Christmas if thats your jam 🙂