Markdown en Astro
Markdown se usa comúnmente para crear contenido con mucho texto como entradas de blog y documentación. Astro incluye soporte integrado para archivos Markdown que también pueden incluir frontmatter YAML (o TOML) para definir propiedades personalizadas como un título, descripción y etiquetas.
En Astro, puedes crear contenido en GitHub Flavored Markdown, y luego renderizarlo en componentes .astro. Esto combina un formato de escritura familiar diseñado para contenido con la flexibilidad de la sintaxis de componentes y la arquitectura de Astro.
Para funcionalidad adicional, como incluir componentes y expresiones JSX en Markdown, añade la integración @astrojs/mdx para escribir tu contenido Markdown usando MDX.
Organizar archivos Markdown
Sección titulada “Organizar archivos Markdown”Tus archivos Markdown locales se pueden guardar en cualquier lugar dentro de tu directorio src/. Los archivos Markdown ubicados dentro de src/pages/ generarán automáticamente páginas Markdown en tu sitio.
Tu contenido Markdown y las propiedades de frontmatter están disponibles para usar en componentes a través de importaciones de archivos locales o cuando se consultan y renderizan a partir de datos obtenidos por una función helper de colecciones de contenido.
Importaciones de archivos vs consultas de colecciones de contenido
Sección titulada “Importaciones de archivos vs consultas de colecciones de contenido”Markdown local se puede importar en componentes .astro usando una declaración import para un solo archivo y import.meta.glob() de Vite para consultar múltiples archivos a la vez. Los datos exportados de estos archivos Markdown se pueden usar luego en el componente .astro.
Si tienes grupos de archivos Markdown relacionados, considera definirlos como colecciones. Esto te da varias ventajas, incluyendo la capacidad de almacenar archivos Markdown en cualquier lugar de tu sistema de archivos o de forma remota.
Las colecciones usan APIs específicas de contenido y optimizadas para consultar y renderizar tu contenido Markdown en lugar de importaciones de archivos. Las colecciones están diseñadas para conjuntos de datos que comparten la misma estructura, como entradas de blog o elementos de producto. Cuando defines esa estructura en un esquema, además obtienes validación, seguridad de tipos e Intellisense en tu editor.
Expresiones dinámicas tipo JSX
Sección titulada “Expresiones dinámicas tipo JSX”Después de importar o consultar archivos Markdown, puedes escribir plantillas HTML dinámicas en tus componentes .astro que incluyan datos de frontmatter y contenido del body.
---title: 'The greatest post of all time'author: 'Ben'---
Here is my _great_ post!---import * as greatPost from "./posts/great-post.md";const compiled = await greatPost.compiledContent();const posts = Object.values(import.meta.glob("./posts/*.md", { eager: true }));---
<p>{greatPost.frontmatter.title}</p><p>Written by: {greatPost.frontmatter.author}</p>
<Fragment set:html={compiled} />
<p>Post Archive:</p><ul> { posts.map((post: any) => ( <li> <a href={post.url}>{post.frontmatter.title}</a> </li> )) }</ul>Propiedades disponibles
Sección titulada “Propiedades disponibles”Markdown de consultas de colecciones de contenido
Sección titulada “Markdown de consultas de colecciones de contenido”Al obtener datos de tus colecciones con las funciones helper getCollection() o getEntry(), las propiedades de frontmatter de tu Markdown están disponibles en un objeto data (p. ej. post.data.title). Además, body contiene el contenido del body sin compilar como una cadena.
La función render() devuelve el contenido del body de tu Markdown, una lista generada de encabezados, así como un objeto frontmatter modificado después de que se hayan aplicado los plugins de Markdown.
Importar Markdown
Sección titulada “Importar Markdown”Las siguientes propiedades exportadas están disponibles en tu componente .astro al importar Markdown usando import o import.meta.glob():
file- La ruta absoluta del archivo (p. ej./home/user/projects/.../file.md).url- La URL de la página (p. ej.,/es/guides/markdown-content).frontmatter- Contiene cualquier dato especificado en el frontmatter YAML (o TOML) del archivo.<Content />- Un componente que devuelve el contenido completo y renderizado del archivo.rawContent()- Una función que devuelve el documento de Markdown sin procesar como una cadena de texto.compiledContent()- Una función asíncrona que devuelve el documento de Markdown compilado como una cadena de texto HTML.getHeadings()- Una función asíncrona que devuelve un array de todos los encabezados (<h1>a<h6>) en el archivo con el tipo:{ depth: number; slug: string; text: string }[]. Elslugde cada encabezado corresponde al ID generado para un encabezado dado y se puede usar para enlaces de anclaje.
Una entrada de blog de Markdown de ejemplo puede pasar el siguiente objeto Astro.props:
Astro.props = { file: "/home/user/projects/.../file.md", url: "/en/guides/markdown-content/", frontmatter: { /** Frontmatter from a blog post */ title: "Astro 0.18 Release", date: "Tuesday, July 27 2021", author: "Matthew Phillips", description: "Astro 0.18 is our biggest release since Astro launch.", }, getHeadings: () => [ {"depth": 1, "text": "Astro 0.18 Release", "slug": "astro-018-release"}, {"depth": 2, "text": "Responsive partial hydration", "slug": "responsive-partial-hydration"} /* ... */ ], rawContent: () => "# Astro 0.18 Release\nA little over a month ago, the first public beta [...]", compiledContent: () => "<h1>Astro 0.18 Release</h1>\n<p>A little over a month ago, the first public beta [...]</p>",}El componente <Content />
Sección titulada “El componente <Content />”El componente <Content /> está disponible importando Content desde un archivo Markdown. Este componente devuelve el contenido completo del body del archivo, renderizado a HTML. Puedes opcionalmente renombrar Content a cualquier nombre de componente que prefieras.
Puedes similarmente renderizar el contenido HTML de una entrada de colección de Markdown renderizando un componente <Content />.
---// Import statementimport {Content as PromoBanner} from '../components/promoBanner.md';
// Collections queryimport { getEntry, render } from 'astro:content';
const product = await getEntry('products', 'shirt');const { Content } = await render(product);---<h2>Today's promo</h2><PromoBanner />
<p>Sale Ends: {product.data.saleEndDate.toDateString()}</p><Content />IDs de encabezados
Sección titulada “IDs de encabezados”Escribir encabezados en Markdown te dará automáticamente enlaces de anclaje para que puedas enlazar directamente a ciertas secciones de tu página.
---title: My page of content---## Introduction
I can link internally to [my conclusion](#conclusion) on the same page when writing Markdown.
## Conclusion
I can visit `https://example.com/page-1/#introduction` in a browser to navigate directly to my Introduction.Astro genera ids de encabezados basándose en github-slugger. Puedes encontrar más ejemplos en la documentación de github-slugger.
IDs de encabezados y plugins
Sección titulada “IDs de encabezados y plugins”Astro inyecta un atributo id en todos los elementos de encabezado (<h1> a <h6>) en archivos Markdown y MDX. Puedes recuperar estos datos desde la utilidad getHeadings() disponible como una propiedad exportada de Markdown de un archivo importado, o desde la función render() cuando se usa Markdown devuelto por una consulta de colecciones de contenido.
Puedes personalizar estos IDs de encabezados con un plugin de procesador de Markdown que inyecte atributos id (p. ej. rehype-slug). Tus IDs personalizados, en lugar de los predeterminados de Astro, se reflejarán en la salida HTML y en los elementos devueltos por getHeadings().
Astro inyecta atributos id después de que tus plugins personalizados se hayan ejecutado, por lo que cualquier ID establecido por un plugin se preserva. Si uno de tus plugins personalizados necesita acceder a los IDs inyectados por Astro, puedes importar el plugin de heading ids de Astro y colocarlo antes de cualquier plugin que dependa de él:
import { defineConfig } from 'astro/config';import { satteri, satteriHeadingIdsPlugin } from '@astrojs/markdown-satteri';import { otherPluginThatReliesOnHeadingIDs } from 'some/plugin/source';
export default defineConfig({ markdown: { processor: satteri({ hastPlugins: [ satteriHeadingIdsPlugin(), otherPluginThatReliesOnHeadingIDs, ], }), },});import { defineConfig } from 'astro/config';import { unified, rehypeHeadingIds } from '@astrojs/markdown-remark';import { otherPluginThatReliesOnHeadingIDs } from 'some/plugin/source';
export default defineConfig({ markdown: { processor: unified({ rehypePlugins: [ rehypeHeadingIds, otherPluginThatReliesOnHeadingIDs, ], }), },});Plugins de Markdown
Sección titulada “Plugins de Markdown”Astro renderiza Markdown usando un procesador de Markdown configurable. Por defecto, este es Sätteri, el pipeline nativo de Markdown y MDX de Astro, incluido con Astro.
Astro aplica GitHub-Flavored Markdown y SmartyPants automáticamente. Esto aporta algunas comodidades como generar enlaces clicables a partir de texto, y formato para citas y guiones largos.
Puedes extender el procesamiento de Markdown con plugins, habilitar características adicionales del parser, o cambiar a un procesador diferente por completo. Consulta la lista completa de opciones de configuración de Markdown.
Elegir un procesador de Markdown
Sección titulada “Elegir un procesador de Markdown”La opción markdown.processor controla qué motor renderiza tus archivos .md y .mdx. Astro proporciona dos opciones oficiales:
satteri()(predeterminado): el pipeline nativo de Sätteri, un compilador rápido de Markdown y MDX con su propio modelo de plugins. Incluido con Astro, por lo que no se necesita instalación adicional.unified(): el pipeline de remark y rehype, con su gran ecosistema de plugins. Proporcionado por@astrojs/markdown-remark, que instalas por separado.
Usar plugins y características de Sätteri
Sección titulada “Usar plugins y características de Sätteri”El procesador satteri() predeterminado acepta sus propios plugins a través de mdastPlugins y hastPlugins, y activa características opcionales del parser a través de features. Consulta la documentación de Sätteri para los plugins y características disponibles.
Importa satteri de @astrojs/markdown-satteri y pasa tus opciones a través de markdown.processor. Este ejemplo añade un plugin mdast y habilita la característica de parser directive:
import { defineConfig } from 'astro/config';import { satteri } from '@astrojs/markdown-satteri';import { myMdastPlugin } from './my-satteri-plugin.mjs';
export default defineConfig({ markdown: { processor: satteri({ mdastPlugins: [myMdastPlugin()], features: { directive: true }, }), },});Cambiar al procesador unified
Sección titulada “Cambiar al procesador unified”Para usar remark y rehype en lugar de Sätteri, instala @astrojs/markdown-remark, luego importa unified y pásalo a markdown.processor:
npm install @astrojs/markdown-remarkpnpm add @astrojs/markdown-remarkyarn add @astrojs/markdown-remarkimport { defineConfig } from 'astro/config';import { unified } from '@astrojs/markdown-remark';
export default defineConfig({ markdown: { processor: unified(), },});Cambiar de procesador reemplaza Sätteri tanto para archivos .md como .mdx. Cualquier plugin de Sätteri en tu configuración no se aplicará. Para usar remark y rehype solo para archivos .mdx, establece la opción processor en la integración MDX en su lugar.
Usar plugins de remark y rehype
Sección titulada “Usar plugins de remark y rehype”El procesador unified() acepta plugins de terceros de remark y rehype. Estos plugins te permiten extender tu Markdown con nuevas capacidades, como auto-generar una tabla de contenidos, aplicar etiquetas accesibles de emoji, y aplicar estilos a tu Markdown.
¡Te animamos a explorar awesome-remark y awesome-rehype para plugins populares! Consulta el README de cada plugin para instrucciones de instalación específicas.
Después de cambiar al procesador unified(), pasa tus plugins a través de markdown.processor. Este ejemplo aplica remark-toc y rehype-accessible-emojis a archivos Markdown:
import { defineConfig } from 'astro/config';import { unified } from '@astrojs/markdown-remark';import remarkToc from 'remark-toc';import { rehypeAccessibleEmojis } from 'rehype-accessible-emojis';
export default defineConfig({ markdown: { processor: unified({ remarkPlugins: [[remarkToc, { heading: 'toc', maxDepth: 3 }]], rehypePlugins: [rehypeAccessibleEmojis], }), },});Personalizar un plugin de remark o rehype
Sección titulada “Personalizar un plugin de remark o rehype”Para personalizar un plugin, proporciona un objeto de opciones después de él en un array anidado.
El ejemplo siguiente añade la opción heading al plugin remarkToc para cambiar dónde se coloca la tabla de contenidos, y la opción behavior al plugin rehype-autolink-headings para añadir la etiqueta de anclaje después del texto del encabezado.
import { defineConfig } from 'astro/config';import { unified } from '@astrojs/markdown-remark';import remarkToc from 'remark-toc';import rehypeSlug from 'rehype-slug';import rehypeAutolinkHeadings from 'rehype-autolink-headings';
export default defineConfig({ markdown: { processor: unified({ remarkPlugins: [[remarkToc, { heading: 'contents' }]], rehypePlugins: [rehypeSlug, [rehypeAutolinkHeadings, { behavior: 'append' }]], }), },});Modificar frontmatter programáticamente
Sección titulada “Modificar frontmatter programáticamente”Cuando uses el procesador remark/rehype, puedes añadir propiedades de frontmatter a todos tus archivos Markdown y MDX con un plugin de remark o rehype.
-
Añade una
customPropertya la propiedaddata.astro.frontmatterdesde el argumentofilede tu plugin:example-remark-plugin.mjs export function exampleRemarkPlugin() {// All remark and rehype plugins return a separate functionreturn function (tree, file) {file.data.astro.frontmatter.customProperty = 'Generated property';}}Agregado en:astro@2.0.0data.astro.frontmattercontiene todas las propiedades de un documento Markdown o MDX dado. Esto te permite modificar las propiedades de frontmatter existentes, o calcular nuevas propiedades a partir de este frontmatter existente. -
Aplica este plugin a tu configuración de integración
markdownomdx:astro.config.mjs import { defineConfig } from 'astro/config';import { unified } from '@astrojs/markdown-remark';import { exampleRemarkPlugin } from './example-remark-plugin.mjs';export default defineConfig({markdown: {processor: unified({ remarkPlugins: [exampleRemarkPlugin] }),},});o
astro.config.mjs import { defineConfig } from 'astro/config';import mdx from '@astrojs/mdx';import { unified } from '@astrojs/markdown-remark';import { exampleRemarkPlugin } from './example-remark-plugin.mjs';export default defineConfig({integrations: [mdx({processor: unified({ remarkPlugins: [exampleRemarkPlugin] }),}),],});
Ahora, cada archivo Markdown o MDX tendrá customProperty en su frontmatter, haciéndolo disponible al importar tu markdown y desde la propiedad Astro.props.frontmatter en tus layouts.
Extender la configuración de Markdown desde MDX
Sección titulada “Extender la configuración de Markdown desde MDX”La integración MDX de Astro extenderá la configuración de Markdown existente de tu proyecto por defecto, incluyendo el procesador de Markdown. Para sobrescribir opciones individuales, puedes especificar su equivalente en tu configuración MDX.
El siguiente ejemplo usa un resaltador de sintaxis diferente y un conjunto diferente de plugins para archivos .mdx que para archivos .md:
import { defineConfig } from 'astro/config';import { satteri } from '@astrojs/markdown-satteri';import mdx from '@astrojs/mdx';
export default defineConfig({ markdown: { syntaxHighlight: 'prism', processor: satteri({ mdastPlugins: [mdastPlugin1] }), }, integrations: [ mdx({ // `markdown.syntaxHighlight` gets overridden for `.mdx` files by this option syntaxHighlight: 'shiki',
// `markdown.processor` gets overridden for `.mdx` files with a different plugin processor: satteri({ mdastPlugins: [mdastPlugin2] }), }) ]});Para evitar extender tu configuración de Markdown desde MDX, establece la opción extendMarkdownConfig (habilitada por defecto) en false:
import { defineConfig } from 'astro/config';import { satteri } from '@astrojs/markdown-satteri';import mdx from '@astrojs/mdx';
export default defineConfig({ markdown: { processor: satteri({ mdastPlugins: [mdastPlugin] }), }, integrations: [ mdx({ // Markdown config now ignored extendMarkdownConfig: false, // Default `satteri()` processor used with no plugins }) ]});Páginas Markdown individuales
Sección titulada “Páginas Markdown individuales”Las colecciones de contenido y importar Markdown en componentes .astro proporcionan más características para renderizar tu Markdown y son la forma recomendada de manejar la mayor parte de tu contenido. Sin embargo, puede haber momentos en los que quieras la conveniencia de simplemente añadir un archivo a src/pages/ y que se cree automáticamente una página simple para ti.
Astro trata cualquier archivo soportado dentro del directorio /src/pages/ como una página, incluyendo .md y otros tipos de archivos Markdown.
Colocar un archivo en este directorio, o cualquier subdirectorio, construirá automáticamente una ruta de página usando el nombre de ruta del archivo y mostrará el contenido Markdown renderizado a HTML. Astro añadirá automáticamente una etiqueta <meta charset="utf-8"> a tu página para facilitar la creación de contenido no ASCII.
---title: Hello, World---
# Hi there!
This Markdown file creates a page at `your-domain.com/page-1/`
It probably isn't styled much, but Markdown does support:- **bold** and _italics._- lists- [links](https://astro.build)- <p>HTML elements</p>- and more!Propiedad layout de frontmatter
Sección titulada “Propiedad layout de frontmatter”Para ayudar con la funcionalidad limitada de las páginas Markdown individuales, Astro proporciona una propiedad especial de frontmatter layout que es una ruta relativa a un componente de layout de Markdown de Astro. layout no es una propiedad especial cuando se usan colecciones de contenido para consultar y renderizar tu contenido Markdown, y no se garantiza que sea soportado fuera de su caso de uso previsto.
Si tu archivo Markdown está ubicado dentro de src/pages/, crea un componente de layout y añádelo en esta propiedad layout para proporcionar un contenedor de página alrededor de tu contenido Markdown.
---layout: ../../layouts/BlogPostLayout.astrotitle: Astro in briefauthor: Himanshudescription: Find out what makes Astro awesome!---This is a post written in Markdown.Este componente de layout es un componente regular de Astro con propiedades específicas disponibles automáticamente a través de Astro.props para tu plantilla de Astro. Por ejemplo, puedes acceder a las propiedades de frontmatter de tu archivo Markdown a través de Astro.props.frontmatter:
---const {frontmatter} = Astro.props;---<html> <head> <!-- ... --> <meta charset="utf-8"> // no longer added by default </head> <!-- ... --> <h1>{frontmatter.title}</h1> <h2>Post author: {frontmatter.author}</h2> <p>{frontmatter.description}</p> <slot /> <!-- Markdown content is injected here --> <!-- ... --></html>Cuando uses la propiedad layout de frontmatter, debes incluir la etiqueta <meta charset="utf-8"> en tu layout ya que Astro ya no la añadirá automáticamente. Ahora también puedes aplicar estilos a tu Markdown en tu componente de layout.
Obtener Markdown remoto
Sección titulada “Obtener Markdown remoto”El procesador de Markdown interno de Astro no está disponible para procesar Markdown remoto.
Para obtener Markdown remoto para usar en colecciones de contenido, puedes construir un loader personalizado con acceso a una función renderMarkdown().
Para obtener Markdown remoto directamente y renderizarlo a HTML, necesitarás instalar y configurar tu propio parser de Markdown desde NPM. Esto no heredará ninguna de las configuraciones de Markdown integradas de Astro que hayas configurado.
Asegúrate de entender estas limitaciones antes de implementar esto en tu proyecto, y considera obtener tu Markdown remoto usando un loader de colecciones de contenido en su lugar.
---// Example: Fetch Markdown from a remote API// and render it to HTML, at runtime.// Using "marked" (https://github.com/markedjs/marked)import { marked } from 'marked';const response = await fetch('https://raw.githubusercontent.com/wiki/adam-p/markdown-here/Markdown-Cheatsheet.md');const markdown = await response.text();const content = marked.parse(markdown);---<article set:html={content} />