![Create React App Officially Deprecated Amid React 19 Compatibility Issues](https://cdn.sanity.io/images/cgdhsj6q/production/04fa08cf844d798abc0e1a6391c129363cc7e2ab-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Create React App Officially Deprecated Amid React 19 Compatibility Issues
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
markdown-rambler
Advanced tools
Yet another opinionated & powerful static site generator.
Turns directories with Markdown files into static websites.
type
to enable different layouts and plugins.type
.application/ld+json
).<meta name="robots" content="noindex">
)--watch
mode for auto re-generation.See webpro.nl and github.com/webpro/webpro.nl for an example website powered by Markdown Rambler.
.
└── content
├── articles
│ ├── starting-a-blog.md
│ ├── writing-a-blogpost.md
│ └── yet-another-article
│ ├── index.md
│ └── image.webp
├── blog.md
└── index.md
const rambler = new MarkdownRambler();
rambler.run();
.
└── dist
├── articles
│ ├── starting-a-blog
│ │ └── index.html
│ ├── writing-a-blogpost
│ │ └── index.html
│ └── yet-another-article
│ ├── index.html
│ └── image.webp
├── blog
│ └── index.html
├── index.html
└── sitemap.txt
And all URLs in /sitemap.txt
:
https://example.org/
https://example.org/articles/starting-a-blog
https://example.org/articles/writing-a-blogpost
https://example.org/articles/yet-another-article
https://example.org/blog
See the tests to get an impression of the conversion from Markdown to HTML.
Option | Type | Default value | Description |
---|---|---|---|
contentFiles | string | string[] | '**/*' | Include Markdown and assets |
contentDir | string | string[] | ['content'] | Directories containing Markdown |
ignorePattern | string | /^(\.|node_modules)/ | File pattern(s) to ignore with --watch |
publicDir | string | 'public' | Directory containing public assets |
outputDir | string | 'dist' | Output directory |
sitemap | boolean | true | Generates sitemap.txt |
feed | Feed | false | Generates feed.xml (RSS) |
search | Search | false | Generates MiniSearch index |
Option | Type | Default value | Description |
---|---|---|---|
verbose | boolean | false | Logs more output about the process |
watch | boolean | false | Add watcher to re-process modified files |
formatMarkdown | boolean | false | Formats source Markdown files (using Prettier) |
Option | Type | Default value | Description |
---|---|---|---|
host | string | '' | Host (e.g. 'https://example.org' ) |
name | string | '' | Website name |
language | string | 'en' | Website language (e.g. 'fr-BE' ) |
manifest | false | string | false | Link to PWA manifest file |
type | TypeFn | page | Add type to each page meta data (e.g. 'article' ) |
defaults | Record<PageType, PageOptions> | undefined | Default meta data for each document |
In order of exection:
Option | Type | Default value | Description |
---|---|---|---|
parsers | Pluggable[] | parsers | Remark parsers |
directives | Record<string, any> | undefined | Directives to extend Markdown syntax |
remarkPlugins | Pluggable[] | remarkPlugins | Additional remark plugins |
remarkRehypeOptions | RemarkRehypeOptions | {} | Options for remark-rehype |
rehypePlugins | Pluggable[] | rehypePlugins | Additional rehype plugins |
renderers | Pluggable[] | renderers | Plugins to render (stringify) the hast |
type Feed = {
pathname: string;
title: string;
description?: string;
author?: string;
tags?: string[];
filter?: (type: string, vFile: VFile) => boolean;
};
type Search = {
outputDir?: string;
filter?: (type: string, vFile: VFile) => boolean;
};
Generates a MiniSearch index file to be used in your client. Here's a minimal example of a client script to use the search index:
(async () => {
await import('https://cdn.jsdelivr.net/npm/minisearch@4.0.3/dist/umd/index.min.js');
const searchIndex = await fetch('/_search/index.json').then(response => response.text());
const index = MiniSearch.loadJSON(searchIndex, { fields: ['title', 'content'] });
const searchBox = document.querySelector('input[type=search]');
const search = query => {
const results = index.search(query, { prefix: true, fuzzy: 0.3 });
console.log(results);
};
searchBox.addEventListener('input', event => {
search(event.target.value);
});
})();
The script(s) can be added to e.g. the public
folder and its path to the defaults.page.scripts
array.
Set formatMarkdown: true
and the following plugins will be applied to the Markdown source files:
[text](url)
into [text][ref]
(and add definitions to the end)type TypeFn = (filename: string, matter: FrontMatter) => PageType;
Example:
{
type: filename => (filename.match(/^blog\//) ? 'article' : 'page');
}
Sets default for each type of page. By default there's only the page
type. Example:
const options = {
defaults: {
page: {
layout: '[See "Layout" below]'
stylesheets: ['/css/stylesheet.css'],
author: {
name: 'Lars Kappert',
href: 'https://www.webpro.nl',
twitter: '@webprolific'
},
publisher: {
name: 'Lars Kappert',
href: 'https://www.webpro.nl',
logo: {
src: 'https://www.webpro.nl/img/logo-512x512.png'
}
},
icon: {
src: '/img/logo.svg'
},
logo: {
alt: 'Blog Logo',
src: '/img/logo.svg',
href: '/'
},
sameAs: ['https://github.com/webpro'],
layout: () => {},
prefetch: '/blog'
}
}
};
Any Front Matter in the Markdown augments or overrides these defaults.
---
published: 2022-03-05
modified: 2022-04-20
image: /articles/yet-another-article/image.webp
draft: true
---
# Yet Another Article
Lorem ipsum
The merged meta data will be used in the meta tags and structured content, and is available in layouts and directives.
published
date adds <meta property="article:published_time" content="2022-03-05T00:00:00Z">
author.name
adds <meta name="author" content="Lars Kappert">
prefetch
value will add <link rel="prefetch" href="/blog">
See the PageOptions
type for details.
Each page type can have its own layout to wrap the content. Render ${node}
somewhere, and use all of the page's meta
data that was provided by Markdown Rambler, merged in with the provided default configuration:
import { html } from 'markdown-rambler';
export default (node, meta) => {
const { logo } = meta;
return html`
<header>
<a href="${logo.href}">
<img src="${logo.src}" alt="${logo.alt}" />
</a>
</header>
<main class=${meta.class}>${node}</main>
<footer>© 2022, Lars Kappert</footer>
`;
};
In this example, the class
field of the Front Matter of each Markdown file would be added to the <main>
element,
while the default.page.class
option could serve as a fallback class
value.
The default remark plugins:
These can be entirely replaced with different parsers
, or extended using remarkPlugins.
Use remarkPlugins
to add remark plugins (to work with
the mdast before it is converted to hast).
Use remarkRehypeOptions
to pass options to
remark-rehype.
The default rehype plugins:
Use rehypePlugins
to add rehype plugins (to work with
the hast after it is converted from mdast).
Use the renderers
option to replace these default render plugins.
Directives are a powerful way to extend the Markdown syntax. The (implemented) proposal consists of inline (:
), leaf
(::
) and container (:::
) block directives.
::ASIDE
# Header
:::div{.wrapper}
Content with :abbr[HTML]{title="HyperText Markup Language"}
:::
The inline and container directives are readily available. To use a leaf block directive, pass an object with the
directive as a key, and a function that returns a hast
node. The function is much like an AST visitor function, and
adds the vFile
argument for convenience:
type DirectiveVisitor = (node: Element, index: number, parent: Parent, vFile: VFile) => Element;
const insertAside = (node, index, parent, vFile) => {
return h('aside', { class: 'custom' }, 'news');
};
const directives = {
ASIDE: insertAside
};
This will result in this HTML output:
<aside class="custom">news</aside>
<h1>Header</h1>
<div class="wrapper">Content with <abbr title="HyperText Markup Language">HTML</abbr></div>
FAQs
Yet another opinionated & powerful static site generator.
The npm package markdown-rambler receives a total of 0 weekly downloads. As such, markdown-rambler popularity was classified as not popular.
We found that markdown-rambler demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.