provides excellent support for using components inside markdown (.mdx
), as well as using markdown components inside Vue.
MDX is a format that combines JSX and Markdown, allowing you to embed components in markdown, and use markdown content inside component slots.
---
date: 2020-10-14
---
# Markdown 📖
<Iles/> provides excellent support for using components inside markdown (`.mdx`),
as well as using markdown components inside Vue.
exposes frontmatter properties so that they can be referenced directly in MDX.
---
title: Both of these
description: Will be available as variables in the component.
---
<Tip title={ title }>
{ description }
</Tip>
If you need all properties, you can use the frontmatter
object.
<Summary { ...frontmatter }/>
The filename
and the page href
can be accessed through meta
.
<SuggestChangesLink filename={ meta.filename }/>
You can mark an individual document as unpublished by using draft: true
.
---
title: Still not ready
draft: true
---
By default, draft pages and documents will be displayed in development, but will be excluded when building the site. Use drafts to override this behavior.
extends MDX enabling you to use components from different frameworks in MDX files.
HMR is fully supported, and components can be used without importing them.
Components can receive markdown content using slots:
<Tip title="Markdown in Slots">
This is a _markdown-based_ comment. **Great!**
</Tip>
Markdown in SlotsThis is a markdown-based comment. Great!
The syntax of MDX is different from Vue templates when it comes to binding dynamic values.
Instead of :title="example"
, you would do title={example}
:
export const example = 'Variables in Markdown'
<Tip title={example}>
You can access the document's `frontmatter`, and `meta` info injected by <Iles/>.
And use expressions, such as { meta.lastUpdated.toLocaleDateString('en-US') }.
</Tip>
Variables in MarkdownYou can access the document's
frontmatter
, andmeta
info injected by .And use expressions, such as 10/27/2022.
Markdown files can be used as Vue components, and they will be automatically imported if they are placed in the components dir.
<script setup>
import Acknowledgements from '~/components/Acknowledgements.mdx' // not needed
</script>
<template>
<Acknowledgements/>
</template>
They can also be used in MDX files as components, which is the easiest way to reuse footers or sections that are repeated across documents.
import Acknowledgements from '~/components/Acknowledgements.mdx' // not needed
And _without_ further ado:
<Acknowledgements/>
When importing an MDX component from Vue, you can render its content using <component>
, and access frontmatter
and meta
as properties in the module:
<script setup lang="ts">
import doc from '~/pages/introduction.mdx'
</script>
<template>
<h1>
<a :href="doc.href">{{ doc.title }}</a>
</h1>
<p>{{ doc.frontmatter.description }}</p>
<component :is="doc"/>
<span>Last Updated: {{ formatDate(doc.meta.lastUpdated) }}</span>>
</template>
You can use any components from src/components or those globally registered in Vue without manually importing them in MDX.
If you would like to replace built-in tags such as img
and a
with
custom components, or provide other components, there are two main options.
Use the mdxComponents option to override elements globally in all MDX documents.
import ResponsiveImage from '~/components/ResponsiveImage.vue'
export default defineApp({
mdxComponents: {
img: ResponsiveImage,
},
})
Recommended ✨Easy to setup, and provides consistency in how documents are rendered across the site.
If you need more control, you can use the components
prop in MDX components.
<script setup>
import Introduction from '~/pages/introduction.mdx'
import Footer from '~/components/SpecialFooter.vue'
const components = { Footer }
</script>
<template>
<h1>{{ Introduction.title }}</h1>
<Introduction :components="components"/>
</template>
Use provideMDXComponents
to override elements and components in all nested components. For example, to override components in all pages that use a specific layout:
<script setup>
import { provideMDXComponents } from 'iles'
import Footer from '~/components/PostFooter.vue'
provideMDXComponents({ Footer })
</script>
...
If you need to provide several slots to a component in MDX, you can use v-slots
:
export const titleWithMarkdown = <span>But better keep it <b>simple</b></span>
<Tip warn v-slots={{ title: () => titleWithMarkdown }}>
The syntax is confusing, and you can often achieve the same using props.
</Tip>
But better keep it simpleThe syntax is confusing, and you can often achieve the same using props.