fubits.dev fubits.dev

Astro Feature Test: MDX from CMS

It works. Even with Svelte.

MDXSvelteAstro
How to use Notion as a visual rich text MDX editor

Astro Component

import ContentNote from '@components/ContentNote.astro';

<ContentNote>
	Test: Plain Astro Component with `click` event listener
	<button onclick="alert('button clicked')">Test</button>
</ContentNote>

Test: Plain Astro Component with click event listener

Svelte Component

Caution: the empty line between the import statement and the <Component /> is mandatory.

import Counter from '@components/Counter.svelte';

<Counter client:visible="svelte" value="5" />

5

Caution: Currently, there’s a known bug in Astro and component styles aren’t imported properly at build time

Update: using Notion code blocks

Using a custom transformer for notion-to-md:

n2m.setCustomTransformer('code', async (block) => {
	/**
	 *   type: 'code',
	 *   code: { caption: [], rich_text: [ [Object] ], language: 'markdown' }
	 */
	const { code } = block

	if (code?.language === 'markdown') {
		return code?.rich_text?.map((chunk) => chunk?.plain_text)?.join('')
	}

	return block
})

the input with language === markdown:

<Counter client:visible="svelte" value="10" />

will be treated as a mdx component reference:

10

Bonus - lazyload Svelte component (hydrate on demand)

The trick is to

  • wrap the component in an Astro HTML wrapper with display: none
  • use the client:visible directive
  • programatically change the visibility of the wrapper which will trigger the component import and the hydration

0

Sources