Headings
The comark/plugins/headings plugin extracts the page title and description from the top of a document and stores them in tree.meta.title and tree.meta.description. By default it reads the first h1 as the title and the first p as the description, and removes both nodes from the tree so they are not rendered twice.
Basic Usage
import { parse } from 'comark'import headings from 'comark/plugins/headings'const result = await parse(content, { plugins: [headings()]})console.log(result.meta.title) // "My Page Title"console.log(result.meta.description) // "First paragraph text."Configuration Options
titleTag
The element tag to read the title from. Defaults to 'h1'.
headings({ titleTag: 'h2' })descriptionTag
The element tag to read the description from. Defaults to 'p'. Change to 'blockquote' if you prefer to use a block quote as the lead-in description.
headings({ descriptionTag: 'blockquote' })remove
Whether to remove the extracted nodes from the tree after extraction. Defaults to true.
// Extract metadata but keep nodes in the rendered outputheadings({ remove: false })Examples
Default extraction
# My Page TitleThis is the opening paragraph used as the description.## Section OneMore content here.import { parse } from 'comark'import headings from 'comark/plugins/headings'const result = await parse(content, { plugins: [headings()]})console.log(result.meta.title) // "My Page Title"console.log(result.meta.description) // "This is the opening paragraph used as the description."// result.nodes no longer contains the h1 or the first pBlockquote as description
Some writing styles use a blockquote as a lead-in instead of a plain paragraph.
# My Page Title> A highlighted lead-in sentence shown as the description.Regular content starts here.import headings from 'comark/plugins/headings'const result = await parse(content, { plugins: [headings({ descriptionTag: 'blockquote' })]})console.log(result.meta.description) // "A highlighted lead-in sentence shown as the description."Combining with the TOC plugin
import { parse } from 'comark'import headings from 'comark/plugins/headings'import toc from 'comark/plugins/toc'const result = await parse(content, { plugins: [headings(), toc()]})console.log(result.meta.title) // page titleconsole.log(result.meta.description) // page descriptionconsole.log(result.meta.toc) // table of contentsAPI Reference
headings(options?): ComarkPlugin
Parameters:
interface HeadingsOptions { titleTag?: string // Tag to extract as title (default: 'h1') descriptionTag?: string // Tag to extract as description (default: 'p') remove?: boolean // Remove extracted nodes from tree (default: true)}Returns: A Comark plugin that writes to tree.meta.title and tree.meta.description.
How It Works
The plugin runs after parsing and scans the top-level nodes of the tree, skipping bare text nodes and <hr> elements:
- If the first content node matches
titleTag, its flattened text is written totree.meta.title. - The next content node is then checked against
descriptionTag. If it matches, its text is written totree.meta.description. When no title node was found, this check starts from the very first content node instead. - If
removeistrue(the default), both matched nodes are spliced out oftree.nodes.
Notes
- Neither
meta.titlenormeta.descriptionis set when the corresponding node is absent or does not match the configured tag. - The description check always looks at the node immediately after the title — a non-matching node between them will prevent description extraction.
- Use
remove: falsewhen you want the metadata available but still need the nodes rendered (e.g. when a custom component handles theh1display).
See Also
- Summary Plugin - Extract content before a
<!-- more -->delimiter - Table of Contents Plugin - Generate hierarchical navigation from headings
- Parse API - Full parse API reference