Markdown 📖

îles provides excellent support for using components inside markdown (.mdx), as well as using markdown components inside Vue.

What is MDX?

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.

The introduction of this MDX page.

Frontmatter and Meta 📃

îles 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 }/>

Markdown Drafts 📝

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.

Components in Markdown 🧱

îles 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.

Markdown in Slots

Components can receive markdown content using slots:

<Tip title="Markdown in Slots">
This is a _markdown-based_ comment. **Great!**
</Tip>
Markdown in Slots

This is a markdown-based comment. Great!

Binding Dynamic Values

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 Markdown

You can access the document's frontmatter, and meta info injected by îles.

And use expressions, such as 10/27/2022.

Markdown in Vue

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

Rendering and Frontmatter

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>

Advanced: Override Elements (Shortcodes)

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.

Override Components Globally

Use the mdxComponents option to override elements globally in all MDX documents.

import ResponsiveImage from '~/components/ResponsiveImage.vue'

export default defineApp({
  mdxComponents: {
    img: ResponsiveImage,
  },
})

src/app.ts

Recommended ✨

Easy to setup, and provides consistency in how documents are rendered across the site.

Override Components Explicitly

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>

...

src/layouts/post.vue

Advanced: Multiple Slots in MDX

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 simple

The syntax is confusing, and you can often achieve the same using props.

Last Updated: