Automatically add a description to the frontmatter of your markdown in Astro
1) Install using the command npm i astro-remark-description
2) Add plugin to astro.config.mjs
import { defineConfig } from 'astro/config';
import remarkDescription from 'astro-remark-description'
export default defineConfig({
markdown: {
remarkPlugins: [
[remarkDescription, {}]
]
}
});
Type: string
Default: 'description'
Name of key inside frontmatter
Type: boolean
Default: false
Render node to a string of HTML
Type: boolean
Default: false
-
true
: if frontmatter property already exists, replace it -
false
: if frontmatter property already exists, skip file
Type: number
Default: 0
Number of nodes to skip before grabbing text
For example, if the first pragraph contains an image, use { skip: 1 }
to get the text of the next paragraph
Type: unist-util-is
test
Tag name tests: "blockquote" | "break" | "code" | "definition" | "delete" | "emphasis" | "footnoteDefinition" | "footnoteReference" | "heading" | "html" | "image" | "imageReference" | "inlineCode" | "link" | "linkReference" | "list" | "listItem" | "paragraph" | "strong" | "table" | "tableCell" | "tableRow" | "text" | "thematicBreak" | "yaml" | "root"
Default: 'paragraph'
A test for finding nodes when looping over markdown to get text
Type: 'paragraph' | 'root' | 'blockquote' | 'delete' | 'emphasis' | 'footnoteDefinition' | 'heading' | 'link' | 'linkReference' | 'list' | 'listItem' | 'strong' | 'table' | 'tableCell' | 'tableRow'
Default: 'root'
Type of the parent node
For exmaple, if the text for your description is inside a list, the parent must be 'listItem'
Function to transfrom the description text before it is added to the frontmatter
Type:
type transform = (
description: string,
data: {
path: string,
cwd: string,
frontmatter: Record<string, any> | undefined
node: Node
}
) => any
Example 1:
Only use the first sentence of description text
{
transform: (desc) => desc.split('.')[0] + '.'
}
Example 2:
Capitalize all description text
{
transform: (desc) => desc.toUpperCase()
}
A function to control the plugin options of each file
Type:
type filter = (
options: Options,
data: {
path: string,
cwd: string,
frontmatter: Record<string, any> | undefined
}
) => Options | false | null | undefined | void
Example 1:
Skip over any files that have scrape: false
in the frontmatter or are located inside the "projects" collection
{
filter: (options, { path, frontmatter }) => {
if (!frontmatter.scrape || path.startsWith('/src/content/projects'))
return false // Return falsey value to skip
return options
}
}
Example 2:
Apply an edge case to a specific file
{
filter: (options, { path }) => {
if (path == '/src/content/blog/post-3.md')
options.skip = 2 // skip first 2 paragraphs
return options
}
}
import { defineConfig } from 'astro/config';
import remarkDescription from 'astro-remark-description'
export default defineConfig({
markdown: {
remarkPlugins: [
[remarkDescription, { name: 'excerpt' }]
]
}
});
import { defineConfig } from 'astro/config';
import remarkDescription from 'astro-remark-description'
export default defineConfig({
markdown: {
remarkPlugins: [
[remarkDescription, {
name: 'excerpt',
override: true,
// Uppercase first letter in description
transform: (desc) => desc[0].toUpperCase() + desc.slice(1)letter,
filter: (options, { path }) => {
// Skip file if not inside a collection
if (!path.startsWith('/src/content'))
return false
// Use heading for description in 'projects' collection
if (!path.startsWith('/src/content/projects'))
options.node = 'heading'
// Edge case: first paragraph is an image, use the second
if (path === '/src/content/blog/post-3.md')
options.skip = 1
return options
},
}]
]
}
});
import { defineConfig } from 'astro/config';
import remarkDescription from 'astro-remark-description'
import remarkDirective from 'remark-directive'
export default defineConfig({
markdown: {
remarkPlugins: [
remarkDirective,
[remarkDescription, {
node: node => node.type === 'containerDirective' && node.name === 'description'
}]
]
}
});
# Heading
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sed.
:::description
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sed.
:::
import { defineConfig } from 'astro/config';
import remarkDescription from 'astro-remark-description'
export default defineConfig({
markdown: {
remarkPlugins: [
[remarkDescription, {
name: 'excerpt',
node: (node, i, parent) => {
const sibling = parent?.children[i + 1]
return sibling?.type === 'html' && sibling?.value === '<!-- more -->'
}
}]
]
}
});
# Heading
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sed.
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sed.
<!-- more -->