Skip to content

Astro Feature Test: MDX from CMS

How to use Notion as a visual rich text MDX editor

Ilja
Sep 8, 2023 · 2 min read

Astro Component

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

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

Interactive featureview on fubits.dev


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

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" />

Interactive featureview on fubits.dev


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:


Interactive featureview on fubits.dev


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

Interactive featureview on fubits.dev


Sources

Did you enjoy this article?

Recommend it — Standard Reader surfaces well-loved writing to more readers across the network.

Across the AtmosphereDiscussions