컨텐츠로 건너뛰기

@astrojs/ markdoc

Astro 통합 을 통해 Markdoc을 사용하여 컴포넌트, 페이지 및 콘텐츠 컬렉션 항목을 생성할 수 있습니다.

Markdoc을 사용하면 Astro 컴포넌트를 사용하여 Markdown을 향상할 수 있습니다. Markdoc에서 작성된 기존 콘텐츠가 있는 경우 이 통합을 통해 콘텐츠 컬렉션을 사용하여 해당 파일을 Astro 프로젝트로 가져올 수 있습니다.

Astro에는 공식 통합 설정을 자동화하는 astro add 명령이 포함되어 있습니다. 원하는 경우 대신 통합을 수동으로 설치할 수 있습니다.

새 터미널 창에서 다음 명령 중 하나를 실행합니다.

Terminal window
npx astro add markdoc

문제가 발생하면 GitHub에 언제든지 보고하고 아래 수동 설치 단계를 시도해 보세요.

먼저 @astrojs/markdoc 패키지를 설치하세요.

Terminal window
npm install @astrojs/markdoc

그런 다음 integrations 속성을 사용하여 astro.config.* 파일에 통합을 적용합니다.

astro.config.mjs
import { defineConfig } from 'astro/config';
import markdoc from '@astrojs/markdoc';
export default defineConfig({
// ...
integrations: [markdoc()],
});

VS Code를 사용하는 경우 구성된 태그에 대한 구문 강조 및 자동 완성을 포함하는 공식 Markdoc 언어 확장이 있습니다. 자세한 내용은 GitHub에서 언어 서버를 참조하세요.

확장 기능을 설정하려면 다음 내용으로 프로젝트 루트에 markdoc.config.json 파일을 생성하세요.

markdoc.config.json
[
{
"id": "my-site",
"path": "src/content",
"schema": {
"path": "markdoc.config.mjs",
"type": "esm",
"property": "default",
"watch": true
}
}
]

schema 객체를 사용하여 markdoc.config.mjs 파일을 구성 파일로 설정하고 path 속성을 사용하여 Markdoc 파일이 저장되는 위치를 정의합니다. Markdoc은 콘텐츠 컬렉션에만 적용되므로 src/content를 사용할 수 있습니다.

Markdoc 파일은 콘텐츠 컬렉션에서만 사용할 수 있습니다. .mdoc 확장자를 사용하여 콘텐츠 컬렉션에 항목을 추가합니다.

  • 디렉터리src/
    • 디렉터리content/
      • 디렉터리docs/
        • why-markdoc.mdoc
        • quick-start.mdoc

그런 다음 콘텐츠 컬렉션 API를 사용하여 컬렉션을 쿼리하세요.

src/pages/why-markdoc.astro
---
import { getEntryBySlug } from 'astro:content';
const entry = await getEntryBySlug('docs', 'why-markdoc');
const { Content } = await entry.render();
---
<!--`data`를 사용하여 프런트매터 속성에 액세스 -->
<h1>{entry.data.title}</h1>
<!--Content 컴포넌트를 사용하여 Markdoc 콘텐츠 렌더링 -->
<Content />
자세한 내용은 Astro 콘텐츠 컬렉션 문서를 참조하세요.

콘텐츠에 변수를 전달해야 할 수도 있습니다. 이는 A/B 테스트와 같은 SSR 매개변수를 전달할 때 유용합니다.

변수는 Content 컴포넌트를 통해 props로 전달될 수 있습니다.

src/pages/why-markdoc.astro
---
import { getEntryBySlug } from 'astro:content';
const entry = await getEntryBySlug('docs', 'why-markdoc');
const { Content } = await entry.render();
---
<!--`abTest` 매개변수를 변수로 전달합니다.-->
<Content abTestGroup={Astro.params.abTestGroup} />

이제 abTestGroupdocs/why-markdoc.mdoc에서 변수로 사용할 수 있습니다.

src/content/docs/why-markdoc.mdoc
{% if $abTestGroup === 'image-optimization-lover' %}
Let me tell you about image optimization...
{% /if %}

모든 Markdoc 파일에 전역 변수를 생성하기 위해 markdoc.config.mjs|ts 파일에서 variables 속성을 사용할 수 있습니다.

markdoc.config.mjs
import { defineMarkdocConfig } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({
variables: {
environment: process.env.IS_PROD ? 'prod' : 'dev',
},
});

Markdoc 콘텐츠에서 프론트매터에 액세스

섹션 제목: Markdoc 콘텐츠에서 프론트매터에 액세스

entry 객체의 data 속성을 콘텐츠를 렌더링하기 위한 변수로 전달하여 프론트매터에 액세스할 수 있습니다.

src/pages/why-markdoc.astro
---
import { getEntry } from 'astro:content';
const entry = await getEntry('docs', 'why-markdoc');
const { Content } = await entry.render();
---
<Content frontmatter={entry.data} />

이제 Markdoc에서 $frontmatter로 액세스할 수 있습니다.

@astrojs/markdoc은 Markdoc의 모든 기능을 사용하여 UI 컴포넌트를 콘텐츠에 연결하는 구성 옵션을 제공합니다.

Astro 컴포넌트를 Markdoc 태그로 사용

섹션 제목: Astro 컴포넌트를 Markdoc 태그로 사용

.astro 컴포넌트에 매핑되는 Markdoc 태그를 구성할 수 있습니다. 프로젝트 루트에 markdoc.config.mjs|ts 파일을 생성하고 tag 속성을 구성하여 새 태그를 추가할 수 있습니다.

이 예시는 Aside 컴포넌트를 렌더링하고 type prop이 문자열로 전달되도록 허용합니다.

markdoc.config.mjs
import { defineMarkdocConfig, component } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({
tags: {
aside: {
render: component('./src/components/Aside.astro'),
attributes: {
// Markdoc에는 각 속성에 대한 타입 정의가 필요합니다.
// 이는 렌더링 중인 컴포넌트의 'Props' 타입을 반영해야 합니다.
// 속성 정의에 대한 Markdoc의 문서를 참조하세요.
// https://markdoc.dev/docs/attributes#defining-attributes
type: { type: String },
},
},
},
});

이제 이 컴포넌트는 Markdoc 파일에서 {% along %} 태그를 통해 사용할 수 있습니다. 하위 항목은 컴포넌트의 기본 슬롯으로 전달됩니다.

# Welcome to Markdoc 👋
{% aside type="tip" %}
Use tags like this fancy "aside" to add some _flair_ to your docs.
{% /aside %}

클라이언트 측 UI 컴포넌트 사용

섹션 제목: 클라이언트 측 UI 컴포넌트 사용

태그와 노드는 .astro 파일로 제한됩니다. Markdoc에 클라이언트 측 UI 컴포넌트를 포함하려면 원하는 client: 지시어와 함께 프레임워크 컴포넌트를 렌더링하는 래퍼 .astro 컴포넌트를 사용하세요.

이 예시는 React Aside.tsx 컴포넌트를 ClientAside.astro 컴포넌트로 래핑합니다.

src/components/ClientAside.astro
---
import Aside from './Aside';
---
<Aside {...Astro.props} client:load />

이제 이 Astro 컴포넌트는 구성의 모든 태그 또는 노드에 대한 render prop에 전달될 수 있습니다.

markdoc.config.mjs
import { defineMarkdocConfig, component } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({
tags: {
aside: {
render: component('./src/components/ClientAside.astro'),
attributes: {
type: { type: String },
},
},
},
});

npm 패키지 및 TypeScript 파일의 Astro 컴포넌트 사용

섹션 제목: npm 패키지 및 TypeScript 파일의 Astro 컴포넌트 사용

TypeScript 또는 JavaScript 파일에서 명명된 내보내기로 노출된 Astro 컴포넌트를 사용해야 할 수도 있습니다. 이는 npm 패키지와 디자인 시스템을 사용할 때 일반적입니다.

가져오기 이름을 component() 함수의 두 번째 인수로 전달할 수 있습니다.

markdoc.config.mjs
import { defineMarkdocConfig, component } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({
tags: {
tabs: {
render: component('@astrojs/starlight/components', 'Tabs'),
},
},
});

그러면 내부적으로 다음 import 문이 생성됩니다.

import { Tabs } from '@astrojs/starlight/components';

{% partial %} 태그를 사용하면 Markdoc 콘텐츠에서 다른 .mdoc 파일을 렌더링할 수 있습니다.

이는 여러 문서에서 콘텐츠를 재사용하는 데 유용하며, 컬렉션 스키마를 따르지 않는 .mdoc 콘텐츠 파일을 가질 수 있습니다.

이 예시는 블로그 컬렉션 항목에서 사용되는 바닥글의 Markdoc partial을 보여줍니다.

src/content/blog/_footer.mdoc
Social links:
- [Twitter / X](https://twitter.com/astrodotbuild)
- [Discord](https://astro.build/chat)
- [GitHub](https://github.com/withastro/astro)

블로그 게시물 항목 하단에 바닥글을 렌더링하려면 {% partial %} 태그를 사용합니다. 상대 경로 또는 가져오기 별칭을 사용하여 file 속성에 파일의 경로를 적용합니다.

src/content/blog/post.mdoc
# My Blog Post
{% partial file="./_footer.mdoc" %}

@astrojs/markdoc은 코드 블록을 강조 표시하는 ShikiPrism 확장 프로그램을 제공합니다.

extends 속성을 사용하여 Markdoc 구성에 shiki() 확장을 적용합니다. 선택적으로 shiki 구성 객체를 전달할 수 있습니다:

markdoc.config.mjs
import { defineMarkdocConfig } from '@astrojs/markdoc/config';
import shiki from '@astrojs/markdoc/shiki';
export default defineMarkdocConfig({
extends: [
shiki({
// Shiki의 테마 중에서 선택하거나 직접 추가하세요.
// 기본값: 'github-dark'
// https://shiki.style/themes
theme: 'dracula',
// 가로 스크롤을 방지하려면 줄 바꿈을 활성화하세요.
// 기본값: false
wrap: true,
// 사용자 정의 언어 전달
// 참고: Shiki에는 `.astro`를 포함하여 수많은 언어가 내장되어 있습니다!
// https://shiki.style/languages
langs: [],
}),
],
});

extends 속성을 사용하여 Markdoc 구성에 prism() 확장을 적용합니다.

markdoc.config.mjs
import { defineMarkdocConfig } from '@astrojs/markdoc/config';
import prism from '@astrojs/markdoc/prism';
export default defineMarkdocConfig({
extends: [prism()],
});
Prism 스타일시트 구성에 대해 알아보려면 구문 강조 가이드를 참조하세요.

사용자 정의 Markdoc 노드 / 요소

섹션 제목: 사용자 정의 Markdoc 노드 / 요소

단락 및 굵은 텍스트와 같은 표준 Markdown 요소를 Astro 컴포넌트로 렌더링할 수 있습니다. 이를 위해 Markdoc 노드를 구성할 수 있습니다. 특정 노드가 속성을 받으면 해당 속성을 컴포넌트 props로 사용할 수 있습니다.

이 예시는 사용자 정의 Quote.astro 컴포넌트를 사용하여 인용문을 렌더링합니다.

markdoc.config.mjs
import { defineMarkdocConfig, nodes, component } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({
nodes: {
blockquote: {
...nodes.blockquote, // 다른 옵션에 대해서는 Markdoc의 기본값을 적용하세요.
render: component('./src/components/Quote.astro'),
},
},
});
모든 내장 노드 및 속성에 대해 알아보려면 Markdoc 노드 문서를 참조하세요.

@astrojs/markdoc는 제목에 앵커 링크를 자동으로 추가하고 콘텐츠 컬렉션 API를 통해 headings 목록을 생성합니다. 제목을 렌더링하는 방법을 추가로 사용자 정의하려면 Astro 컴포넌트를 Markdoc 노드로 적용하세요.

이 예시에서는 render 속성을 사용하여 Heading.astro 컴포넌트를 렌더링합니다.

markdoc.config.mjs
import { defineMarkdocConfig, nodes, component } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({
nodes: {
heading: {
...nodes.heading, // 기본 앵커 링크 생성 유지
render: component('./src/components/Heading.astro'),
},
},
});

모든 Markdown 제목은 Heading.astro 컴포넌트를 렌더링하고 다음 속성을 컴포넌트 props로 전달합니다.

  • level: number 레벨 1 - 6의 제목
  • id: string 제목의 텍스트 콘텐츠에서 생성된 id입니다. 이는 콘텐츠 render() 함수에 의해 생성된 slug에 해당합니다.

예를 들어 ### Level 3 heading!라는 제목은 level: 3id: 'level-3-heading'을 컴포넌트 props로 전달합니다.

사용자 정의 이미지 컴포넌트

섹션 제목: 사용자 정의 이미지 컴포넌트

Astro의 <Image /> 컴포넌트는 Markdoc에서 직접 사용할 수 없습니다. 그러나 기본 ![]() 이미지 구문이 사용될 때마다 기본 이미지 노드를 재정의하도록 Astro 컴포넌트를 구성하거나 추가 이미지 속성을 지정할 수 있도록 사용자 정의 Markdoc 태그로 구성할 수 있습니다.

Markdoc의 기본 이미지 노드 재정의

섹션 제목: Markdoc의 기본 이미지 노드 재정의

기본 이미지 노드를 재정의하려면 표준 <img> 대신 렌더링되도록 .astro 컴포넌트를 구성할 수 있습니다.

  1. 사용자 정의 MarkdocImage.astro 컴포넌트를 구축하여 이미지의 필수 srcalt 속성을 <Image /> 컴포넌트에 전달합니다.

    src/components/MarkdocImage.astro
    ---
    import { Image } from "astro:assets";
    interface Props {
    src: ImageMetadata;
    alt: string;
    }
    const { src, alt } = Astro.props;
    ---
    <Image src={src} alt={alt} />
  2. <Image /> 컴포넌트에는 ![]() 구문을 사용하여 제공할 수 없는 원격 이미지에 대한 widthheight가 필요합니다. 원격 이미지를 사용할 때 오류를 방지하려면 원격 URL src를 발견했을 때 표준 HTML <img> 태그를 렌더링하도록 컴포넌트를 업데이트하세요.

    src/components/MarkdocImage.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. 기본 이미지 노드를 재정의하고 MarkdocImage.astro를 렌더링하도록 Markdoc을 구성합니다.

    markdoc.config.mjs
    import { defineMarkdocConfig, nodes, component } from '@astrojs/markdoc/config';
    export default defineMarkdocConfig({
    nodes: {
    image: {
    ...nodes.image, // 다른 옵션에 대해서는 Markdoc의 기본값을 적용하세요.
    render: component('./src/components/MarkdocImage.astro'),
    },
    },
    });
  4. 모든 .mdoc 파일의 기본 이미지 구문은 이제 <Image /> 컴포넌트를 사용하여 로컬 이미지를 최적화합니다. 원격 이미지는 계속 사용할 수 있지만 Astro의 <Image /> 컴포넌트에 의해 렌더링되지는 않습니다.

    src/content/blog/post.mdoc
    <!-- <Image />에 의해 최적화 -->
    ![A picture of a cat](/cat.jpg)
    <!-- 최적화되지 않은 <img> -->
    ![A picture of a dog](https://example.com/dog.jpg)

사용자 정의 Markdoc 이미지 태그 생성

섹션 제목: 사용자 정의 Markdoc 이미지 태그 생성

Markdoc image 태그를 사용하면 ![]() 구문으로는 불가능한 이미지의 추가 속성을 설정할 수 있습니다. 예를 들어 사용자 정의 이미지 태그를 사용하면 widthheight가 필요한 원격 이미지에 Astro의 <Image /> 컴포넌트를 사용할 수 있습니다.

다음 단계에서는 이미지를 최적화하기 위해 Astro <Image /> 컴포넌트를 사용하여 캡션이 있는 <figure> 요소를 표시하는 사용자 정의 Markdoc 이미지 태그를 생성합니다.

  1. 필요한 props을 받아 캡션이 포함된 이미지를 렌더링하려면 MarkdocFigure.astro 컴포넌트를 생성합니다.

    src/components/MarkdocFigure.astro
    ---
    // src/components/MarkdocFigure.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. Astro 컴포넌트를 렌더링하도록 사용자 정의 이미지 태그를 구성합니다.

    markdoc.config.mjs
    import { component, defineMarkdocConfig, nodes } from '@astrojs/markdoc/config';
    export default defineMarkdocConfig({
    tags: {
    image: {
    attributes: nodes.image.attributes,
    render: component('./src/components/MarkdocFigure.astro'),
    },
    },
    });
  3. Markdoc 파일의 image 태그를 사용하여 캡션이 있는 그림을 표시하고 컴포넌트에 필요한 모든 속성을 제공합니다.

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

markdoc.config.mjs|ts 파일은 태그함수를 포함한 모든 Markdoc 구성 옵션을 허용합니다.

markdoc.config.mjs|ts 파일의 기본 내보내기에서 다음 옵션을 전달할 수 있습니다.

markdoc.config.mjs
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] ?? '🏳';
},
},
},
});

이제 모든 Markdoc 콘텐츠 항목에서 이 함수를 호출할 수 있습니다.

¡Hola {% getCountryEmoji("spain") %}!
콘텐츠에 변수나 함수를 사용하는 방법에 대한 자세한 내용은 Markdoc 문서를 참조하세요.

Markdoc은 기본적으로 <article> 태그로 문서를 래핑합니다. 이는 document Markdoc 노드에서 변경할 수 있습니다. 래퍼 요소를 제거하려는 경우 HTML 요소 이름 또는 null을 허용합니다.

markdoc.config.mjs
import { defineMarkdocConfig, nodes } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({
nodes: {
document: {
...nodes.document, // 다른 옵션에는 기본값 적용
render: null, // 기본값은 'article'
},
},
});

Astro Markdoc 통합은 markdoc.config.js 파일을 통해 사용할 수 없는 Markdoc 옵션 및 기능 구성을 처리합니다.

Markdoc 태그 및 노드와 함께 HTML 마크업 작성을 활성화합니다.

기본적으로 Markdoc은 HTML 마크업을 의미 있는 콘텐츠로 인식하지 않습니다.

콘텐츠와 함께 HTML 요소를 포함할 수 있는 Markdown과 유사한 경험을 얻으려면 markdoc 통합 옵션으로 allowHTML:true를 설정하세요. 이렇게 하면 Markdoc 마크업에서 HTML 구문 분석이 활성화됩니다.

astro.config.mjs
import { defineConfig } from 'astro/config';
import markdoc from '@astrojs/markdoc';
export default defineConfig({
// ...
integrations: [markdoc({ allowHTML: true })],
});

기본적으로 공백 4개로 들여쓰기된 모든 콘텐츠는 코드 블록으로 처리됩니다. 불행하게도 이 동작은 복잡한 구조를 가진 문서의 가독성을 향상시키기 위해 임의 수준의 들여쓰기를 사용하기 어렵게 만듭니다.

Markdoc에서 중첩 태그를 사용할 때 깊이 수준이 명확하도록 태그 내부의 내용을 들여쓰는 것이 도움이 될 수 있습니다. 임의 들여쓰기를 지원하려면 들여쓰기 기반 코드 블록을 비활성화하고 들여쓰기 기반 코드 블록을 설명하는 몇 가지 다른 markdown-it 구문 분석 규칙을 수정해야 합니다. 이러한 변경 사항은 ignoreIndentation 옵션을 활성화하여 적용할 수 있습니다.

astro.config.mjs
import { defineConfig } from 'astro/config';
import markdoc from '@astrojs/markdoc';
export default defineConfig({
// ...
integrations: [markdoc({ ignoreIndentation: true })],
});
# Welcome to Markdoc with indented tags 👋
# Note: Can use either spaces or tabs for indentation
{% custom-tag %}
{% custom-tag %} ### Tags can be indented for better readability
{% another-custom-tag %}
This is easier to follow when there is a lot of nesting
{% /another-custom-tag %}
{% /custom-tag %}
{% /custom-tag %}

더 많은 통합

UI 프레임워크

SSR 어댑터

기타 통합

기여하기

여러분의 생각을 들려주세요!

GitHub Issue 생성

우리에게 가장 빨리 문제를 알려줄 수 있어요.

커뮤니티