Elder.js Plugin: Markdown
An extensible markdown parser for Elder.js powered by remark.
Use it to create a blog, or site, just configure and it'll parse your markdown and make it available in your Svelte templates.
IMPORTANT: Upstream Shiki changed the name of the themes available. This means if you are upgrading to 1.3.0 from a version before you may need to update your theme name.
Install
npm install --save @elderjs/plugin-markdown
Config
Once installed, open your elder.config.js
and configure the plugin by adding @elderjs/plugin-markdown
to your plugin object.
plugins: {
'@elderjs/plugin-markdown': {
routes: [],
slugFormatter: function(relativeFilePath, frontmatter) {
return false;
},
useSyntaxHighlighting: false
}
}
Example Config
plugins: {
'@elderjs/plugin-markdown': {
routes: ['articles'],
contents: {
blog: 'src/contents/articles'
}
slugFormatter: function(relativeFilePath, frontmatter) {
return false;
},
useSyntaxHighlighting: false,
useGitHubFriendlyMarkdown: false,
}
}
Caveat: Currently, when your contents path is outside of the src directory (eg: rootdir/articles/
) the dev server will not be able to pickup changes on your markdown files. However it can build just fine.
Customizing the Defaults
Below are the default settings of the plugin. You can adjust them to your needs.
plugins: {
'@elderjs/plugin-markdown': {
routes: [],
contents: {}
remarkPlugins: [
frontmatter,
[extractFrontmatter, { name: 'frontmatter', yaml: yaml.parse }],
remarkSlug,
[remarkHtml, { sanitize: false }],
],
useSyntaxHighlighting: {
theme: 'nord'
},
useGitHubFriendlyMarkdown: false,
useElderJsPluginImages: true,
useTableOfContents: false,
createRoutes: true,
},
}
A note on the default syntax highlighting - we use shiki (compared to other well known options) because it highlights everything in inline styles (so no extra JS/CSS needed), has extensive language support, and can use any VS Code theme including your own custom one. We have not yet exposed this last feature to you as an option for this plugin - if you want this feature and are interested in implementing, please feel free to open an issue. If you wish to use your own syntax highlighting, you can add it to your remarkPlugins
array, or set useSyntaxHighlighting: false
and implement separately from this markdown toolchain.
Getting all Markdown For a Route:
An object representing all of the markdown the plugin parsed from the defined routes
is available at data.markdown
.
If you are looking to get an array of the markdown for a specific route such as blog
you can access it data.markdown.blog
.
helpers.markdownParser
:
In addition to parsing the markdown in the given routes, this plugin makes available the configured remark parser at helpers.markdownParser
during the bootstrap
hook.
This means you can use the same markdown parser to parse markdown from other sources if needed.
For full documentation please review remark's docs. That said, the default plugin config can be used to parse markdown like so:
helpers.markdownParser.processSync(mdText)
if you are not using syntax highlighting.helpers.markdownParser.process(mdText)
if you are using syntax highlighting. Note that because this is an async function, it will not run inside of a non-hydrated Svelte file. To get around this, you'll want to execute the function in the data
portion of your route.js
file.
If you need to customize the remark plugins that are used here are some notes:
- The
remarkPlugins
array are added to remark
in the order they are given. - If you add a single plugin in your
elder.config.js
, you must specify a full remark
pipeline. - If a plugin such as
remark-extract-frontmatter
needs an array of options, you can pass in an array like so: remarkPlugins: [[extractFrontmatter, { name: 'frontmatter', yaml: yaml.parse }]]
The default remarkPlugins are exported for ease of use via the package. const { remarkPlugins } = require('@elderjs/plugin-markdown');
Notes:
- By default, if there is a
date
field in your frontmatter it will sort all of the markdown for that route by it. - If there is a
slug
field in your frontmatter it will use that for the slug, if not it falls back to the filename. - If
draft: true
is in a file's frontmatter or a slug is prefixed with draft-
these markdown files will be hidden when process.env.NODE_ENV === 'production'
. They will also be prefixed with DRAFT: [Post Title Here]
to make this functionality more obvious.