Comments (27)
Do you have suggestions on a better alternative?
Several markdown to html generators exist that are well established which simply use the base languages: node, python, go, etc. Instead of using a framework that isn't suited to the task, they focus on structure and features and work on that. By working on the features, structure, and grammar, the tooling will emerge.
1. I want to edit the pages sometimes, and I want to do so using markdown without extra steps.
2. I still want to use React components *sometimes*.
3. I want it to be really easy to deploy and monitor. Nextjs is really easy for those things.
Solving the first issue and third issues don’t require React, but the second definitely does. So I’m still stuck.
Why? What specifically are you using for "website with markdown" that needs React?
> Do you have suggestions on a better alternative?
Yes.
1. For turning markdown into html on the server (i.e. render the HTML on the server and then deliver it) use pandoc. I use it like this for my blog: https://gist.github.com/lelanthran/2634fc2508c93a437ba5ca511...
2. For turning markdown into html on the client, write a custom component that parses the markdown into DOM nodes allowing the page author to simply do `<dynamic-markdown remote-src=some/path/to/page.md>`. You can even use one of the many existing Vanilla JS libraries to do this within the custom component.
In either of those two options above, what value does React add?
example:
<html>
<head><title>hello</title></head>
<body>
<main id=root ></main>
<script src=./marked.min.js async defer ></script>
<script>
async function load() {
let element = document.querySelector("main#root");
await fetch("./index.md")
.then(resp => resp.text())
.then(text => marked(text, { ... }))
.then(html => {
element.innerHTML = html;
});
}
window.onload = load;
</script>
</body>
</html>
since it directly injects the resulting html, you may set "unsafe HTML" option in marked (or markdown.js) and include <title> tags within your markdown document. this will _also_ rewrite the browser title(s)> edit: formatting
Just try to make something without React and you light see the light. It's actually not difficult.
If it is a client-side solution, I'm imagining a single index.html file (with inline JS/CSS) that you could have a content/ or markdown/ child folder for. The HTTP server would have directory listing on for that folder. The index.html file enumerate/fetch the markdown in the content and folder and render it. You could route using the URL hash.
No build process. Just a single file + your markdown content. Maybe I just like this kind of stuff (https://github.com/pseudosavant/player.html, https://github.com/pseudosavant/folder.api)? So tempted to vibe-code an example...
Initially I was using the hash as you suggested, but the redirect/404 was flaky when I use github-pages as the host, hence I reverted to the query-string (? or search) as it creates a complete refresh. Which allows me to set up "virtual" routes like `/blog`.
Topping with worker/service worker, it is quite robust!
Link: https://mert.akeng.in/
But isn't Hugo or Jekyll the easy way to turn markdown into a website?
Jekyll was literally made by github to have a simple way to turn a markdown page into a github pages site. Wasn't it?
Just put an index.md in the root of a empty repo and flip the right flags in Github and have a static site.
https://github.com/obaqueiro/ezmdpage
And inspired by it made a similar thing for mermaid.
https://github.com/obaqueiro/mermaid-js-auto-renderer
Great to add /docs into code repos.
You can see it here: https://rsc-mdx-blog.saewitz.com
It has server-rendered mdx, client components, inline footnotes, layout bleeding, server-rendered code syntax highlighting, content-collections, and opengraph image generation. It can be rendered fully static or from a server. If you choose to deploy it as static, the "server"-rendering just happens at build-time.
It's a really decent starting point for someone who wants an efficient, lean, powerful, and flexible blog.
It is open sourced here: https://github.com/switz/rsc-mdx-blog-starter
1. https://idratherbewriting.com/learnapidoc/pubapis_static_sit...
The output is just a bundle of files for your web server of your choice, supports good navigation with the sidebar, custom theming if you need it (but otherwise gets out of your way), alongside being a single executable.
Seriously, love this simplification of content, and taking care of all the hairy details around `<CustomComponent>...</...>`. It's what the web should have been all along!
Precisely! Thank you.
Can you share more about what you have in mind for frontmatter? I don’t really understand the need/use cases yet.
Basically:
---
import foo, bar, baz
---
# Markdown
* Goes
* <https://here.com>
eg: https://docs.github.com/en/contributing/writing-for-github-d... ... https://jekyllrb.com/docs/front-matter/ ... and google search for "rst yaml frontmatter"If you take an `*.mdx` file and run it through a typical markdown renderer, you'd get something like... well... lemme give the counter-example: if you had the "dashes" delimiting your "frontmatter" from the document, you'd get something like:
<hr>import foo, bar, baz<hr>\n<h1>Markdown</h1><ul><li>...etc...
...the critical part being to relatively unambiguously demarcate "junk" from "content" in the markdown ecosystem. In the far future when this project is but a forgotten memory of time, people can still just straight up render the markdown and "obviously" delete the stuff between the <hr's> up at the top.The contrarian is that there's ambiguity as to when your `*.mdx` "import junk" stops and when the actual content starts. Do you stop parsing [for imports] after the first blank line? Do you stop parsing when you get a syntax error? Do you only parse lines that begin with [import ...]? What about [from ... import ...]?
More google searches: `http header demarcation rfc`, and eg: https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/...
...strong recommendation: demarcate "headers" from content (a-la HTTP). Your format effectively becomes `---\n $PROG_LANG_GOES_HERE ---\n $CONTENT_HERE`, and you slide 1000% into "pure HTTP":
GET /foo.mdx
Content-Type: application/mdx
Date: 2020-10-10 01:02:34
---
import SomeComponent
---
<SomeComponent>My Header</SomeComponent>
* Some
* ContentI've been considering Spinal[0] (no association) to bridge that gap, any others I should be looking at?
I consider my own static site generator [1] much simpler than this. Around 250 SLOC with 4 dependencies (markdown2, pyyaml, jinja2, Pygments)
for I in *.md; do pandoc "$I" --template=template.html --metadata title="My Site" -o "${I%.md}.html"; done CONTENT_DIR := content
BUILD_DIR := public
MD_FILES := $(shell find $(CONTENT_DIR) -name '*.md')
HTML_OUT := $(patsubst $(CONTENT_DIR)/%.md,$(BUILD_DIR)/%.html,$(MD_FILES))
.PHONY: all clean assets serve
all: $(HTML_OUT) assets
assets:
@mkdir -p $(BUILD_DIR) && cp -a static/style.css $(BUILD_DIR)/
$(BUILD_DIR)/%.html: $(CONTENT_DIR)/%.md templates/default.html site.yaml
@mkdir -p $(dir $@)
pandoc --standalone --from gfm --to html5 \
--template=templates/default.html \
--metadata-file=site.yaml \
--toc --toc-depth=3 \
-o $@ $<
Ask ChatGPT, it'll spit out the rest (sample posts, template, CSS, YAML, Makefile, etc)Push updates to the md file and it rebuilds itself.
Just updated it; what’s new:
• Next.js 15.5.2 + React 19.1.1 • Better typing for error boundaries (React 19) • Robust handling for Next 15 async params • Updated DaisyUI, MDX, and tooling
Use it for docs, personal sites, landing pages, or simple content sites that still want modern Next.js ergonomics.
That is not hard to do, if you're okay with adding a script tag in your header.
Not perfect, to be sure, but it lets you create a custom element `<mark-down src=...>` that lets the page author sprinkle markdown everywhere in their page.
You are welcome.
Hmmmmmm no
Seems like markdown is back in vogue. The more the merrier as far as I'm concerned.