Skip to content

Instantly share code, notes, and snippets.

@myobie
Last active January 5, 2024 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save myobie/2f347c3d3ebb40bb743ad1a04487c19e to your computer and use it in GitHub Desktop.
Save myobie/2f347c3d3ebb40bb743ad1a04487c19e to your computer and use it in GitHub Desktop.
Compile an mdx component for SSR preact using deno
import { mdx } from './mdx.ts'
import renderToString from 'preact-render-to-string'
import { type FunctionalComponent } from 'preact'
const MDXContent = await mdx(new URL('./test.mdx', import.meta.url))
const Page: FunctionalComponent = ({ children }) => (
<html lang='en'>
<head>
<title>Example MDX page</title>
<meta charSet='UTF-8' />
</head>
<body>
{children}
</body>
</html>
)
const html = renderToString(
<Page>
<MDXContent />
</Page>
)
console.log('<!doctype html>' + html)
{
"imports": {
"mdx": "https://esm.sh/@mdx-js/mdx",
"preact": "https://esm.sh/preact@10.13.2",
"preact/": "https://esm.sh/preact@10.13.2/",
"preact-render-to-string": "https://esm.sh/*preact-render-to-string@6.0.2"
}
}
import { compile, type UseMdxComponents } from 'mdx'
import { type FunctionalComponent } from 'preact'
export type MDXComponent = FunctionalComponent<ReturnType<UseMdxComponents>>
const cachedComponents: Map<string, MDXComponent> = new Map()
const decoder = new TextDecoder()
export async function mdx(filename: string | URL): Promise<MDXComponent> {
const cached = cachedComponents.get(filename.toString())
if (cached) {
return cached
}
const bytes = await Deno.readFile(filename)
const content = decoder.decode(bytes)
const compiled = await compile(content, { jsxImportSource: 'preact' })
const tmpFilePath = (await Deno.makeTempFile()) + '.js'
await Deno.writeTextFile(tmpFilePath, compiled.value.toString())
const { default: component } = await import(tmpFilePath)
if (!component) {
throw new Error('compilation failed')
}
cachedComponents.set(filename.toString(), component)
return component
}
<!doctype html>
<html lang="en">
<head>
<title>Example MDX page</title>
<meta charSet="UTF-8"/>
</head>
<body>
<h1>Hello world</h1>
<section>
<p>
<strong>hot</strong>
<em>cross</em>
buns.
</p>
</section>
</body>
</html>

export function Block({ children }) { return (

{children}
) }

Hello world

**hot** *cross* buns.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment