astro-markdown-mdx

Markdown y MDX en Astro

  • 5 min

Astro nació con el contenido en mente. A diferencia de otros frameworks donde configurar un blog con Markdown requiere instalar plugins o parseadores, en Astro el soporte para Markdown es nativo.

Markdown es un lenguaje de marcado ligero es limpio, es portátil y no nos obliga a escribir etiquetas HTML para poner una simple negrita.

Probablemente ya estes acostumbardo a usarlo, ya que es ampliamente utilizado para escribir documentación, blogs, y otros tipos de contenido entre desarrolladores y escritores técnicos.

Además Astro va un paso más allá con MDX, que es una mejora de Markdown para hacerlo más dinámico (spoiler, no sale muy bien, luego vemos porqué)

Si quieres aprender más consulta el Curso de Markdown

Markdown estándar (.md)

Astro tiene soporte nativo para Markdown, lo que significa si colocas un archivo Markdown dentro de src/pages, se convertirá automáticamente en una página web.

src/pages/ └── blog/ ├── primer-post.md └── segundo-post.md

Esto generará automáticamente las URLs /blog/primer-post y /blog/segundo-post.

Francamente, poder crear todo el contenido en Markdown es un puntazo 💛. Esta web que ves, está hecha así. Casi todo el contenido es markdown + Astro

Layouts en Markdown

El problema de un archivo .md “crudo” es que, al renderizarse, solo genera el HTML del contenido (párrafos, encabezados, listas). No tiene <html>, ni <head>, ni estilos.

Para solucionarlo, Astro nos permite especificar un Layout en el frontmatter del archivo Markdown.

---
layout: ../../layouts/BlogLayout.astro
title: "Mi viaje aprendiendo Astro"
author: "Luis Llamas"
date: "2023-10-20"
---

# Hola Mundo

Este es el contenido de mi artículo. Astro cogerá todo este texto,
lo convertirá a HTML y lo inyectará en el `<slot />` del layout.
Copied!

Y en nuestro BlogLayout.astro, accedemos a esos datos a través de la prop frontmatter:

---
// src/layouts/BlogLayout.astro
const { frontmatter } = Astro.props;
---
<html>
  <head>
    <title>{frontmatter.title}</title>
  </head>
  <body>
    <h1>{frontmatter.title}</h1>
    <p class="meta">Escrito por {frontmatter.author}</p>
    
    <article class="prose">
      <slot /> </article>
  </body>
</html>
Copied!

El Markdown estándar (.md) es perfecto para contenido puramente textual que no necesita interactividad. Es rápido de procesar y estándar.

MDX: Markdown con JSX

MDX es una extensión de la sintaxis de Markdown que nos permite escribir JSX (JavaScript XML) directamente en nuestros archivos de contenido.

Básicamente: Markdown + Componentes = MDX.

Instalación

A diferencia del Markdown estándar, MDX no viene activado por defecto (aunque es oficial). Debemos añadir la integración.

npx astro add mdx
Copied!

Este comando instalará las dependencias y actualizará tu astro.config.mjs.

Usando componentes en MDX

Imagina que estás escribiendo un tutorial sobre ordenación de arrays y quieres mostrar un componente interactivo que visualice el algoritmo.

En un archivo .md normal, tendrías que poner una imagen estática o un GIF. En un archivo .mdx, puedes importar y usar el componente.

Crea un archivo src/pages/tutorial-sort.mdx:

---
layout: ../../layouts/TutorialLayout.astro
title: "Algoritmos de Ordenación"
---
import VisualizadorSort from '../components/VisualizadorSort.jsx';
import Alerta from '../components/Alerta.astro';

# Introducción

El método de la burbuja es sencillo pero ineficiente.

<Alerta tipo="info">
  Este algoritmo tiene una complejidad de O(n²).
</Alerta>

Aquí puedes verlo en acción:

<VisualizadorSort client:visible />

## Conclusión

Como has podido ver en el componente de arriba...
Copied!

Exportando variables

En MDX también puedes exportar variables desde el contenido para que el Layout las utilice, o incluso usarlas dentro del propio texto.

---
title: "Hola MDX"
---
export const año = 2024;

# Bienvenido al año {año}

Escribiendo esto desde {frontmatter.title}.
Copied!

Diferencias clave

{ models: [ { name: “Markdown (.md)”, color: “#38bdf8” }, { name: “MDX (.mdx)”, color: “#FBBF24” } ], categories: { “Características”: [“Sintaxis”, “Componentes”, “Variables”], “Uso”: [“Curva Aprendizaje”, “Uso ideal”] }, specs: { “Sintaxis”: [“Estándar estricto”, “Markdown + JSX”], “Componentes”: [”❌ No soportados”, “✔️ Imports React”], “Variables”: [“Solo frontmatter”, “JavaScript completo”], “Curva Aprendizaje”: [ { val: 20, max: 100, unit: ”%”, display: “Baja” }, { val: 60, max: 100, unit: ”%”, display: “Media” } ], “Uso Ideal”: [“Blogs, Docs simples”, “Apps interactivas”] } }

En mi caso, no uso MDX. La idea es muy potente, pero a mi nunca me ha funcionado demsiado bien:

  • Me hacia me hacía muy muy muy lento (esta web es muy grande)
  • Me daba más problemas de los que me arreglaba

Pero lo mejor es que si quieres, lo pruebes por ti mismo. Quizás en tu proyecto te sirva.