# My Blog Post


{% partial file="./_footer.mdoc" /%}
```

## Syntax highlighting

[Section titled “Syntax highlighting”](#syntax-highlighting)

`@astrojs/markdoc` provides [Shiki](https://shiki.style) and [Prism](https://github.com/PrismJS) extensions to highlight your code blocks.

### Shiki

[Section titled “Shiki”](#shiki)

Apply the `shiki()` extension to your Markdoc config using the `extends` property. You can optionally pass a shiki configuration object:

markdoc.config.mjs

```js
import { defineMarkdocConfig } from '@astrojs/markdoc/config';
import shiki from '@astrojs/markdoc/shiki';


export default defineMarkdocConfig({
  extends: [
    shiki({
      // Choose from Shiki's built-in themes (or add your own)
      // Default: 'github-dark'
      // https://shiki.style/themes
      theme: 'dracula',
      // Enable word wrap to prevent horizontal scrolling
      // Default: false
      wrap: true,
      // Pass custom languages
      // Note: Shiki has countless langs built-in, including `.astro`!
      // https://shiki.style/languages
      langs: [],
    }),
  ],
});
```

### Prism

[Section titled “Prism”](#prism)

Apply the `prism()` extension to your Markdoc config using the `extends` property.

markdoc.config.mjs

```diff
import { defineMarkdocConfig } from '@astrojs/markdoc/config';
import prism from '@astrojs/markdoc/prism';


export default defineMarkdocConfig({
+  extends: [prism()],
});
```

To learn about configuring Prism stylesheets, [see our syntax highlighting guide](/en/guides/syntax-highlighting/#add-a-prism-stylesheet).

## Custom Markdoc nodes / elements

[Section titled “Custom Markdoc nodes / elements”](#custom-markdoc-nodes--elements)

You may want to render standard Markdown elements, such as paragraphs and bolded text, as Astro components. For this, you can configure a [Markdoc node](https://markdoc.dev/docs/nodes). If a given node receives attributes, they will be available as component props.

This example renders blockquotes with a custom `Quote.astro` component:

markdoc.config.mjs

```js
import { defineMarkdocConfig, nodes, component } from '@astrojs/markdoc/config';


export default defineMarkdocConfig({
  nodes: {
    blockquote: {
      ...nodes.blockquote, // Apply Markdoc's defaults for other options
      render: component('./src/components/Quote.astro'),
    },
  },
});
```

See the [Markdoc nodes documentation](https://markdoc.dev/docs/nodes#built-in-nodes) to learn about all the built-in nodes and attributes.

### Custom headings

[Section titled “Custom headings”](#custom-headings)

`@astrojs/markdoc` automatically adds anchor links to your headings, and [generates a list of `headings` via the content collections API](/en/guides/content-collections/#rendering-body-content). To further customize how headings are rendered, you can apply an Astro component [as a Markdoc node](https://markdoc.dev/docs/nodes).

This example renders a `Heading.astro` component using the `render` property:

markdoc.config.mjs

```js
import { defineMarkdocConfig, nodes, component } from '@astrojs/markdoc/config';


export default defineMarkdocConfig({
  nodes: {
    heading: {
      ...nodes.heading, // Preserve default anchor link generation
      render: component('./src/components/Heading.astro'),
    },
  },
});
```

All Markdown headings will render the `Heading.astro` component and pass the following `attributes` as component props:

* `level: number` The heading level 1 - 6
* `id: string` An `id` generated from the heading’s text contents. This corresponds to the `slug` generated by the [content `render()` function](/en/guides/content-collections/#rendering-body-content).

For example, the heading `### Level 3 heading!` will pass `level: 3` and `id: 'level-3-heading'` as component props.

### Custom image components

[Section titled “Custom image components”](#custom-image-components)

Astro’s `<Image />` component cannot be used directly in Markdoc. However, you can configure an Astro component to override the default image node every time the native `![]()` image syntax is used, or as a custom Markdoc tag to allow you to specify additional image attributes.

#### Override Markdoc’s default image node

[Section titled “Override Markdoc’s default image node”](#override-markdocs-default-image-node)

To override the default image node, you can configure an `.astro` component to be rendered in place of a standard `<img>`.

1. Build a custom `MarkdocImage.astro` component to pass the required `src` and `alt` properties from your image to the `<Image />` component:

   src/components/MarkdocImage.astro

   ```astro
   ---
   import type { ImageMetadata } from "astro";
   import { Image } from "astro:assets";
   interface Props {
     src: ImageMetadata;
     alt: string;
   }
   const { src, alt } = Astro.props;
   ---
   <Image src={src} alt={alt} />
   ```

2. The `<Image />` component requires a `width` and `height` for remote images which cannot be provided using the `![]()` syntax. To avoid errors when using remote images, update your component to render a standard HTML `<img>` tag when a remote URL `src` is found:

   src/components/MarkdocImage.astro

   ```diff
   ---
   import type { ImageMetadata } from "astro";
   import { Image } from "astro:assets";
   interface Props {
     src: ImageMetadata | string;
     alt: string;
   }
   const { src, alt } = Astro.props;
   ---
   -<Image src={src} alt={alt} />
   +{
     +typeof src === 'string' ? <img src={src} alt={alt} /> : <Image src={src} alt={alt} />
   +}
   ```

3. Configure Markdoc to override the default image node and render `MarkdocImage.astro`:

   markdoc.config.mjs

   ```js
   import { defineMarkdocConfig, nodes, component } from '@astrojs/markdoc/config';


   export default defineMarkdocConfig({
     nodes: {
       image: {
         ...nodes.image, // Apply Markdoc's defaults for other options
         render: component('./src/components/MarkdocImage.astro'),
       },
     },
   });
   ```

4. The native image syntax in any `.mdoc` file will now use the `<Image />` component to optimize your local images. Remote images may still be used, but will not be rendered by Astro’s `<Image />` component.

   src/content/blog/post.mdoc

   ```md
   <!-- Optimized by <Image /> -->
   ![A picture of a cat](/cat.jpg)


   <!-- Unoptimized <img> -->
   ![A picture of a dog](https://example.com/dog.jpg)
   ```

#### Create a custom Markdoc image tag

[Section titled “Create a custom Markdoc image tag”](#create-a-custom-markdoc-image-tag)

A Markdoc `image` tag allows you to set additional attributes on your image that are not possible with the `![]()` syntax. For example, custom image tags allow you to use Astro’s `<Image />` component for remote images that require a `width` and `height`.

The following steps will create a custom Markdoc image tag to display a `<figure>` element with a caption, using the Astro `<Image />` component to optimize the image.

1. Create a `MarkdocFigure.astro` component to receive the necessary props and render an image with a caption:

   src/components/MarkdocFigure.astro

   ```astro
   ---
   import type { ImageMetadata } from "astro";
   import { Image } from "astro:assets";


   interface Props {
     src: ImageMetadata | string;
     alt: string;
     width: number;
     height: number;
     caption: string;
   }


   const { src, alt, width, height, caption } = Astro.props;
   ---
   <figure>
       <Image {src} {alt} {width} {height}  />
       {caption && <figcaption>{caption}</figcaption>}
   </figure>
   ```

2. Configure your custom image tag to render your Astro component:

   markdoc.config.mjs

   ```ts
   import { component, defineMarkdocConfig, nodes } from '@astrojs/markdoc/config';


   export default defineMarkdocConfig({
     tags: {
       image: {
         attributes: {
           width: {
             type: String,
           },
           height: {
             type: String,
           },
           caption: {
             type: String,
           },
           ...nodes.image.attributes
         },
         render: component('./src/components/MarkdocFigure.astro'),
       },
     },
   });
   ```

3. Use the `image` tag in Markdoc files to display a figure with caption, providing all the necessary attributes for your component:

   ```md
   {% image src="./astro-logo.png" alt="Astro Logo" width="100" height="100" caption="a caption!" /%}
   ```

## Advanced Markdoc configuration

[Section titled “Advanced Markdoc configuration”](#advanced-markdoc-configuration)

The `markdoc.config.mjs|ts` file accepts [all Markdoc configuration options](https://markdoc.dev/docs/config), including [tags](https://markdoc.dev/docs/tags) and [functions](https://markdoc.dev/docs/functions).

You can pass these options from the default export in your `markdoc.config.mjs|ts` file:

markdoc.config.mjs

```js
import { defineMarkdocConfig } from '@astrojs/markdoc/config';


export default defineMarkdocConfig({
  functions: {
    getCountryEmoji: {
      transform(parameters) {
        const [country] = Object.values(parameters);
        const countryToEmojiMap = {
          japan: '🇯🇵',
          spain: '🇪🇸',
          france: '🇫🇷',
        };
        return countryToEmojiMap[country] ?? '🏳';
      },
    },
  },
});
```

Now, you can call this function from any Markdoc content entry:

```md
¡Hola {% getCountryEmoji("spain") %}!
```

[See the Markdoc documentation](https://markdoc.dev/docs/functions#creating-a-custom-function) for more on using variables or functions in your content.

### Set the root HTML element

[Section titled “Set the root HTML element”](#set-the-root-html-element)

Markdoc wraps documents with an `<article>` tag by default. This can be changed from the `document` Markdoc node. This accepts an HTML element name or `null` if you prefer to remove the wrapper element:

markdoc.config.mjs

```js
import { defineMarkdocConfig, nodes } from '@astrojs/markdoc/config';


export default defineMarkdocConfig({
  nodes: {
    document: {
      ...nodes.document, // Apply defaults for other options
      render: null, // default 'article'
    },
  },
});
```

## Integration config options

[Section titled “Integration config options”](#integration-config-options)

The Astro Markdoc integration handles configuring Markdoc options and capabilities that are not available through the `markdoc.config.js` file.

### `allowHTML`

[Section titled “allowHTML”](#allowhtml)

**Type:** `boolean`\
**Default:** `false`

**Added in:** `@astrojs/markdoc@0.4.4`

Enables writing HTML markup alongside Markdoc tags and nodes.

By default, Markdoc will not recognize HTML markup as semantic content.

To achieve a more Markdown-like experience, where HTML elements can be included alongside your content, set `allowHTML:true` as a `markdoc` integration option. This will enable HTML parsing in Markdoc markup.

astro.config.mjs

```diff
  import { defineConfig } from 'astro/config';
  import markdoc from '@astrojs/markdoc';


  export default defineConfig({
    // ...
+    integrations: [markdoc({ allowHTML: true })],
  });
```

Caution

When `allowHTML` is enabled, HTML markup inside Markdoc documents will be rendered as actual HTML elements (including `<script>`), making attack vectors like XSS possible. Ensure that any HTML markup comes from trusted sources.

### `ignoreIndentation`

[Section titled “ignoreIndentation”](#ignoreindentation)

**Type:** `boolean`\
**Default:** `false`

**Added in:** `@astrojs/markdoc@0.7.0`

By default, any content that is indented by four spaces is treated as a code block. Unfortunately, this behavior makes it difficult to use arbitrary levels of indentation to improve the readability of documents with complex structure.

When using nested tags in Markdoc, it can be helpful to indent the content inside of tags so that the level of depth is clear. To support arbitrary indentation, we have to disable the indent-based code blocks and modify several other markdown-it parsing rules that account for indent-based code blocks. These changes can be applied by enabling the ignoreIndentation option.

astro.config.mjs

```diff
  import { defineConfig } from 'astro/config';
  import markdoc from '@astrojs/markdoc';


  export default defineConfig({
    // ...
+    integrations: [markdoc({ ignoreIndentation: true })],
  });
```

```md