Docksaurusでは記事をMarkdown形式で記述することができ、ヘッダー情報はFront matter で記述することができます。 記事の中でFront matterやmetadataの値を取得する方法を調査しました。
Front matterとは
Markdownの先頭部分に---
で囲んだエリアにYaml形式で記述します。
---
id: doc-with-tags
title: A doc with tags
tags:
- Demo
- Getting started
---
## 見出し
ここが内容です。
このMarkdownはこのような表示となります。
環境
2023/01/07の最新バージョン2.2.0で確認しました。
記事の種類について
Docusaurusでは記事を投稿する方法として、以下の3種類があります。
- Doc
- Page
- Blog
Front matterの値を取得する方法
ドキュメントに記載がありました。(リンク)
---
id: doc-with-tags
title: A doc with tags
tags:
- Demo
- Getting started
---
## 見出し
ここが内容です。
+ <ul>
+ {Object.entries(frontMatter).map(([key, value]) => <li key={key}><b>{key}</b>: {value}</li>)}
+ </ul>
もっと簡単に<div>{frontMatter.id}</div>
で参照ができます。
tocとcontentTitleの値を取得する方法
Front matterと同じ方法で取得できる値としてtoc
とcontentTitle
もあります。
toc
---
id: doc-with-tags
title: A doc with tags
tags:
- Demo
- Getting started
---
## 見出し
ここが内容です。
# H1
H1
## H2
H2
### toc
<div>{JSON.stringify(toc, null, 2)}</div>
contentTitle
---
id: doc-with-tags
title: A doc with tags
tags:
- Demo
- Getting started
---
# タイトル(H1見出し)
## 見出し
ここが内容です。
### contentTitle
<div>{contentTitle}</div>
contentTitle
はMarkdown先頭にあるh1
ヘッダーが対象になります。先頭にない場合はundefined
になります。
metadataの値を取得する方法
ドキュメントに記載はありませんが、metadata
も同様の方法で取得可能です。
---
id: doc-with-tags
title: A doc with tags
tags:
- Demo
- Getting started
---
# タイトル
## 見出し
ここが内容です。
### metadata
<div>{JSON.stringify(metadata, null, 2)}</div>
Front matterで取得できるid
、title
の他にもdescription
やsource
、permalink
などもあります。frontMatterも含まれてますね。
JSON
{
"unversionedId": "test/doc-with-tags",
"id": "test/doc-with-tags",
"title": "A doc with tags",
"description": "見出し",
"source": "@site/docs/test/test/index.md",
"sourceDirName": "test",
"slug": "/test/",
"permalink": "/docs/test/test/",
"draft": false,
"tags": [
{
"label": "Demo",
"permalink": "/docs/test/tags/demo"
},
{
"label": "Getting started",
"permalink": "/docs/test/tags/getting-started"
}
],
"version": "current",
"frontMatter": {
"id": "doc-with-tags",
"title": "A doc with tags",
"tags": [
"Demo",
"Getting started"
]
},
"sidebar": "tutorialSidebar"
}
Front matterやmetadataの値を独自コンポーネントで使用する
独自コンポーネントの場合は直接frontMatter
を操作することはできません。
---
id: doc-with-tags
title: A doc with tags
tags:
- Demo
- Getting started
---
# タイトル
## 見出し
ここが内容です。
import MyComponent from '@site/src/components/Test'
<MyComponent />
import React from 'react';
export default function MyComponent() {
return (
<>
<ul>
{Object.entries(frontMatter).map(([key, value]) => <li key={key}><b>{key}</b>: {value}</li>)}
</ul>
<div>{frontMatter.id}</div>
<div>{JSON.stringify(toc, null, 2)}</div>
<div>{contentTitle}</div>
<div>{JSON.stringify(metadata, null, 2)}</div>
</>
)
}
独自コンポーネントの場合はuseDoc
というhookが用意されていますので、これを使用するとFront matterなどにアクセスすることが可能になります。
import React from 'react';
import { useDoc } from '@docusaurus/theme-common/internal';
export default function MyComponent() {
const { metadata, frontMatter, toc, contentTitle } = useDoc()
return (
<>
<ul>
{Object.entries(frontMatter).map(([key, value]) => <li key={key}><b>{key}</b>: {value}</li>)}
</ul>
<div>{frontMatter.id}</div>
<div>{JSON.stringify(toc, null, 2)}</div>
<div>{contentTitle}</div>
<div>{JSON.stringify(metadata, null, 2)}</div>
</>
)
}
うまくいきました。
ただ、残念なことにuseDoc
はDoc形式の場合のみ利用可能です。
- Page形式で
useDoc
を呼び出した場合
Blog形式の場合はuseDoc
の代わりにuseBlogPost
を使用するとfrontMatter
、metadata
、toc
は取得が可能です。(contentTitle
は取得できませんでした。)
import React from 'react';
import { useBlogPost } from '@docusaurus/theme-common/internal';
export default function MyComponent() {
const { metadata, frontMatter, toc, contentTitle } = useBlogPost()
console.log(frontMatter)
return (
<>
<ul>
{Object.entries(frontMatter).map(([key, value]) => <li key={key}><b>{key}</b>: {value}</li>)}
</ul>
<div>{frontMatter.id}</div>
<div>{JSON.stringify(toc, null, 2)}</div>
<div>{contentTitle}</div>
<div>{JSON.stringify(metadata, null, 2)}</div>
<div>contentTitleのタイプ:{(typeof contentTitle)}</div>
</>
)
}
Page形式の際の方法はわかりませんでした。
doc/page/blogで共通して使用できるFront matterやmetadataの値を使用する独自コンポーネントを作成する
作成しているコンテンツの形式を気にするのが面倒な場合は、Markdownからpropsとして渡すのが良いでしょう。
import React from 'react';
- import { useDoc, type DocContextValue } from '@docusaurus/theme-common/internal';
- export default function MyComponent() {
+ export default function MyComponent({ metadata, frontMatter, toc, contentTitle }) {
- const { metadata, frontMatter, toc, assets, contentTitle } = useDoc() as DocContextValue
return (
<>
<ul>
{Object.entries(frontMatter).map(([key, value]) => <li key={key}><b>{key}</b>: {value}</li>)}
</ul>
<div>{frontMatter.id}</div>
<div>{JSON.stringify(toc, null, 2)}</div>
<div>{contentTitle}</div>
<div>{JSON.stringify(metadata, null, 2)}</div>
</>
)
}
---
id: doc-with-tags
title: A doc with tags
tags:
- Demo
- Getting started
---
# タイトル
## 見出し
ここが内容です。
import MyComponent from '@site/src/components/Test'
- <MyComponent />
+ <MyComponent
+ metadata={metadata}
+ frontMatter={frontMatter}
+ toc={toc}
+ contentTitle={contentTitle} />
Doc形式
Page形式
Blog形式
metadata
の値は形式ごとに異なります。