As I fell into the SSG pit I found I mostly wrote about and fooled around with the SSG itself, instead of all the things I originally planned on writing about and doing. So I threw away the SSG and installed Wordpress and stopped caring. It's been liberating.
If the goal is to tinker and write about the tinkering, that is fine. If you're not like me and the tinkering never gets in the way of the writing, that's also fine. But that wasn't me. I had to learn yet again that the best tool was the one that got out of my way and let me do what I came to do.
The last thing I need when I'm aiming to write is a chance to procrastinate.
* It and all its plugins must be kept up to date or else you will be compromised.
* The BDFL is a maniac who is happy to block access to deliver or receive security updates for petty personal reasons.
With a static site there are no security vulnerabilities to patch, so it doesn't matter if the SSG project totally implodes because the maintainer goes crazy. With WordPress it matters a lot.
Even if the dude tries to paint the internet with Wordpress's brains, I'm confident I will have time (and the impetus, finally) to find an acceptable alternative for my workflow. I'm open to suggestions.
Also, as I mentioned to a sibling response, the upkeep really is not that much work. It's a personal blog and takes a grand total of three (maybe four) clicks to update every once in a while.
WordPress has no governance, it just has Matt, and wo betide anyone who ticks him off (or who relies on any developers who tick him off).
Of course, WordPress.com is updated differently to a blog running the wordpress.org code.
A few years ago I wanted to own my data again and not depend on external services, so exported the Disqus comments and after playing around with Serendipity ended up with Wordpress.
Was able to import the comments and the Markdown pages and there are even plugins to make it publish everything in the Fediverse. Made it all work using SQLite and enabled auto-updates. It’s basically maintenance-free.
The only thing I really wanted was 1 command to publish (which is does great) and an easy way to drag and drop images into posts (which I can do via the publish jupyter notebook function).
What I absolutely did not want was anything where "send HTML to clients" created any sort of overhead like a database.
Why? Because it takes too much maintenance (keep it up to date ornbecome part of a botnet) for features you probably don't need. A static site generator is totally fine for most blogs and if it needs maintenance it is at a time of your own choice.
My update process is:
- Click a button to back up
- Click a button to update everything
- Open my blog to make sure it still looks normal
Definitely not onerous. To be fair I don't use many plugins, and my theme is very simple. I don't think a plain old blog doesn't need many plugins.
Sometimes I take a break from blogging. I don't want to have to read documentation on how my SSG works (either my own docs or docs on some website) to remember the script to generate the updates, or worry about deploying changes, or fiddling with updates that break my scripts, or anything like that. I do stuff like this for my day job.
I like my blogging experience to be focused on a single thing: writing.
Not a thing you'de need to do with a static website. If you're like: "Hey, I am not doing it right now and I am fine", consider that your warning. I have been hosting wordpress instances since wordpress existed and I know how things can go wrong with them.
Whereas the concerns for something like WordPress is
1. Has our website been hacked and publicly defaced?
2. Has our website been silently hacked and is being used to secretly distributing malware or worse, aka the FBI randomly shows up at your business.
3. Will updating one random plugin nuke your entire live site, resulting in multiple sleepless nights? Will not updating it cause your site to get hacked also resulting in sleepless nights?
4. Or better yet something in your underlying environment changes and nukes your site, usually in the middle of a weekend out with your family, and your hosting provider pinky swears they didn't change anything. So you spend your whole weekend investigating just to find out your provider did change something, usually something stupid too.
5. Considering all the above your off-site backup solution is vital so better keep that maintained and thoroughly tested as well.
6. Plus a thousand other reasons to waste time, worry, and lose sleep.
If I were choosing a CMS or tech stack for a critical piece of infrastructure my requirements would be different and I might find some other tool.
Also, if all these were so much concern, I doubt so much of the web would run on Wordpress. Yes, you need to keep your install and plugins up to date. But you need to keep your toolchain up to date no matter what you use. Risk of breakage on update is a thing everywhere, not just Wordpress. I'm by no means a Wordpress fan, but it really is not as bad as it's painted.
I used to run a company that all we did was wordpress, joomla, and drupal maintenance, performance optimization, and hack recovery. It very much was and mostly continues to be that bad.
> Risk of breakage on update is a thing everywhere, not just Wordpress.
Ya the issue with server side rendering is that your live environment is made of up dozens to hundreds of difference software stacked on top of each other and they all pretty much need to work perfectly to actually work and or not be vulnerable. And if you use something standard like cpanel to manage your environment, add another 1000 layers of complexity to the stack.
And lets not even go into all the work it takes to have that environment have decent performance and run on reasonably priced hardware.
Where as my concerns for my SSG live environments basically amounts to, is the host publicly accessible? To be vulnerable you would need to do something very stupid like set file permissions to 777 or something.
I personally don't think it's that much work, and definitely not complicated, to keep my software up to date. And as a blog all I need to do is cache / throw behind a CDN and I'm golden. Nothing complex going on here. No headaches, no late nights, not even a wink of worry.
And if your blog was serving malware, or really nasty porn, or taking part in a DDoS?
> Also, if all these were so much concern, I doubt so much of the web would run on Wordpress.
What is it that gives you that kind of faith in the industry's decision-making processes?
1- Make sure to order post by date (most recent first) and to display that date somewhere. The date can simply be taken from the post file meta data (e.g. creation time) to keep things minimal.
2- An RSS feed of course! It should be quite easy to generate a minimal one with only links and titles based on the existing script and a minimal RSS template.
being "followed" isn't always a good thing, it can create pressure to pander to your audience, the same thing that makes social media bad.
RSS creates no such pressure, as you needn't be aware of who/what is following you. It's a convenience function simply for the convenience, rather than as a form and measure of external validation.
the fact that people want to read every new thing being posted is external validation, rather than letting each piece stand alone by its merit.
Personally, I blog in my head but am concerned still it could lead to bias in my other activities which are mainly related to sitting under a tree by a lake in the middle of nowhere.
I tend to expect most useful sources of high-quality information to have a fair amount of off-topic content, since it's hard to reach critical mass on a single narrow niche. I read Hacker News, but click maybe 10% of the links
Worrying about this “pressure” is a great way to be that guy with three posts about their new static site generator and nothing else.
I agree. A blog is literally a web log. A chronological sequence of posts published on the web. RSS is certainly helpful for syndication and distribution but I wouldn't consider it to be a defining part of what a web log is.
As soon as you start catering to and fishing for views you lose that angle. Not a drama, but it’s already 99.5% of the internet.
Edit : I really like Marginalia search, for prioritizing non commercial content.
1- I'm leaning towards an automatically generated file containing metadata, TOML or such
2- RSS is definitely coming, but is dependent on point 1 :-)
Starting with a simple collection of pages was a great way to get started and set up a minimum viable website. But as time passed, I found myself needing a few more features. In order of priority, these included:
1. RSS feeds.
2. A blog listing page with posts ordered by date.
3. The ability to tag posts by topic and generate tag-based index pages.
4. Support for non-blog content, like tools, games, demos, etc. that can also be tagged and included in the RSS feed.
5. Support for comments without relying on third-party services.
With each new requirement, the source code gradually grew. What started as a few hundred lines has now expanded to around 1300 lines of Common Lisp. Not too big in the grand scheme of things but not exactly tiny either. Still, I try to resist the temptation to keep adding every shiny new idea that comes to mind. This remains a solo passion project. I want the entire source code to be something I can hold in my head at once. If I encounter a bug, I want it to be something I can reason about and fix in under 10 minutes, and so far, fortunately, that has been the case.
That said, new ideas are always tempting. Lately, I've been enticed by the idea of adding a blogroll that provides a list of posts from my favourite bloggers. This could replace my usual feed reader. I haven't had the time to implement it yet, but if a quiet weekend comes along, that might just be the next feature I work on. Of course, I remind myself not to let this project spiral out of control. I certainly don't want this to grow into something that can read my email.
See my source code here:
https://github.com/brilee/modern-descartes-v2/blob/master/ma...
Includes:
1. RSS feed
2. Blog listing pages ordered by date
3. Tagging system
4. Localhost dev server with file-watching recompilation step.
Here's my current iteration, a python script that does manage to stay under 1000 lines: https://github.com/llimllib/obsidian_notes/blob/c93b9b5c46fe...
I've done derived pages like post sets, indexes, and slideshows. Tag flavors for people and video games. Then just total control over how normal widgets like thumbnail galleries and pull quotes look and feel.
Might be useful as a high level reference
If browsers can decide to render PDFs, surely a simple formatter and user-decidable stylesheets for markdown/gemini content can’t be that hard to ship.
As it stands you can write a text/plain blog but you will be hurt with SEO concerns since it isn’t really hypertext (maybe you could do some magic with link headers). Supporting other formats lowers the barrier to publishing in a neat manner and gives control back to users.
Sadly, I can see why it's unlikely that we'd get this.
First, browsers would need to agree on which flavor of Markdown, what extensions, and so on. After all, Markdown is almost like the CSV of text formats, with everyone doing their own thing ("almost" because you can still assume that some basic things work as you'd expect).
Only with that, I can already see the backlash no matter what they choose to do here. Too minimal, and get complains about not being too useful. Choose some extensions, get complains about being bloated. Make any attempt to have a thoughtful discussion about pros and cons (short and long term), get shut down with "don't let perfect be the enemy of good".
If we can get past that and finally agree on one specific set of features, there's still the question of whether it's actually worth it or not. The difference between Markdown and PDF is that reading PDFs directly in the browser is a common enough activity, but reading Markdown directly is only going to benefit the tiny audience of the small percentage of software devs that exist in the world, and maybe 5 weird people. Everyone else with a blog would just use the WYSIWYG from their CMS.
That's why I wouldn't be surprised if I don't see native Markdown rendering during my lifetime.
The correct answer is CommonMark. At that point extensions don't matter, since there's a common enough base that a Markdown document written with unsupported extensions in mind will still look decent. Reference code is abundant and permissively licensed. There's no good reason to pick any other flavor (and most other flavors are compatible enough with CommonMark for it to be a non-issue anyway).
They do that with JS (or at least they did at one point). Similar libraries exist for XSLT if you want newer versions than what browsers natively support, for jpegxl, and many other formats.
So every time your post contains the string 'Minimum viable blog', it will be replaced by the title of the current post? That’s a bug, right?
• Trailing slashes in HTML content (apart from SVG/MathML) are completely useless, unless you’re serving the document in XML syntax (which you can’t do by accident). I personally think they’re harmful, because they encourage an incorrect belief, and are seldom even applied consistently.
• <html>, <head>, </head>, <body>, </body> and <html> are all optional. In practice, you should have an <html lang> attribute so that you can’t omit that tag, but the others can normally all be omitted.
• In case-insensitive things, lowercase will normally compress better. But Brotli messes things up because it’s a popularity contest of the HTML that people actually write, so that <!DOCTYPE html> compresses better than <!doctype html>, and even <meta charset="utf-8"> compresses better than <meta charset=utf-8>. Anyway, <meta charset="UTF-8" /> would be better as <meta charset="utf-8">.
• In <meta name="viewport" content="width=device-width, initial-scale=1.0" />, the space after the comma, and the .0 in initial-scale, are unnecessary. (In fact, in theory the .0 might not even be parsed: the badly-incomplete-and-extremely-dodgy spec says to use strtod, which is locale-dependent, so a French machine might parse initial-scale=1.5 as only one, ignoring the .5 because it’s not ,5. In practice I’d be mildly surprised if browsers used the real locale-dependent strtod, though I haven’t checked. If some spec somewhere says “assume LC_ALL=C in such cases”, which would also largely resolve the problem, I’d like to know.)
All up (and with title fixed to be a proper placeholder, as discussed):
<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>{{ title }}</title>
<style>
html {
color-scheme: light dark;
font-family: system-ui, sans-serif;
max-width: 70ch;
padding: 3em 1em;
margin: auto;
line-height: 1.5;
font-size: 1.25em;
}
</style>
<a href="/" id="head-link">Carl Öst Wilkens' Blog</a>
{{ content }}
* You can get away with const title = lines.match(/# (.+)/)[1] and avoid frontmatter.
* My blogs never have so many posts they need pagination or tags, or categories, or sorting.
* JSX turns out to be a great vanilla server side string builder if you use a questionable hack like https://immaculata.dev/guides/enabling-jsx.html
* GH Pages with arbitrary build steps instead of (sigh) Jekyll is really easy now with things like https://immaculata.dev/guides/using-gh-pages.html
* highlight.js is still basically the king of super easy code syntax highlight by adding literally three lines to your HTML (shiki is cool but slooooow)
This is what I did:
- Use Hugo Blog Awesome theme
- Followed the 512kb guidelines and verified the page size.
- Stripped down any images and unwanted JS, but there weren't many.
Since that time I have moved to something more sophisticated and now run Astro for my personal site and blog and honestly it's freaking awesome. On their landing page they claim it's the best platform for "content driven sites" and after using it for 6 months I have to say I agree, they take all the BS out of building a blog and just give you clear and easy to follow conventions for just about everything you'd want for a blog.
Bun has a —hot flag that regenerates static html on change.
IntelliJ IDE can detect a // language=html comment above strings which formats the html inside and does highlighting etc.
Just using vanilla JS functions instead of a template language lets you write any logic yourself instead of looking up the template languages way of doing it.
Source: https://github.com/agubelu/blog
But as you invest time and effort, get more readers and asks from your readers, your need for features even for a simple blog will increase. At least basic conversation around content. You will probably end up using Discuss or decide to make your simple blog much more complex by introducing a database (or may even be just flat files on S3).
At some point you will either focus on only "writing" and sharing ideas in which case a simple publishing infra is good. If you want more, you will probably end up building a Jekyll, Hugo etc. from scratch or better adopt and contribute to one of these :)
If you don't start from scratch, the biggest problem with static websites is maintaining old URLs. At some point you need URL rewrite rules, and then you can't just have static files on a server. You need server rules.
It's also nice to just editing text files locally without having to install stuff. Then you need some sort of build system on another server.
Then you might find that you need forms, comments and other features beyond text on a page.
Basically, it's hard to have just static files.
I decided on running an instance of Grav, which is a flat file CMS, with a fairly minimalist theme, except I version all of the files (even the PHP dependencies) in my Git repo, from which I build Docker images that actually get deployed: https://getgrav.org/
The benefit here is that I can launch it locally and see how the blog posts look, it's just a bunch of files unlike SSG, but with dynamic templating, meaning that I also get an updated index of the pages, as well as search functionality out of the box.
Furthermore, each new post is basically a deploy of a new version of the container, which curiously also means that if something goes wrong (e.g. if it gets hacked), there is no serious data loss because none of the data is meant to be truly persistent, I don't even need to think that much about backing it up, rather just the Git repo its built from.
Plus, there's a nice admin UI if I need it (behind additional auth through the web server), or I can just write things in a text editor of my choice locally.
Oh, and the performance is pretty good, too, because there is no database to hit with complex SQL, more like some disk I/O (which also is lessened by the cache).
Since we're chatting about our static site generators - I've been working on mine for a few months and naturally spend way more time on the generator than the content. ;) Mine is written in TypeScript and I'm targeting HTML 4.01 Strict for compat with old browsers.
It started pretty simple, just walk a directory of .md files and output .html, but it now has RSS, Atom, tags, a "latest" page, sitemap, stats, table of contents, SEO features, etc.
It's been fun - a nice "easy" project to slowly polish over time and to gradually grow my TS skills.
I also generate an index page and an RSS feed.
One thing that's been bugging me more recently (now that I have tens of articles written) is that I need to implement incremental rebuilds. Right now every page needs to get regenerated at once, which takes triple-digit-milliseconds. Unacceptable!
I haven't profiled anything though, it could also be the syntax highlighting being slow (it generates quite a soup of HTML tags).
The markdown2 package includes an option for syntax highlighting. You need to bring your own css though.
I think same could also be achieved via React, but I did not want any `npm install` hence, I used some JS libraries like marked and markdown.js directly at the frontend. (Added as git submodules)
I also sort-of liked how a dependency management mechanism could be built directly on top of the git submodules, without requiring an explicit package manager. Given the commits cloned are already pinned and committed to the repository. Though, the tooling is not as good as the well-established dependency management software like Maven, NPM, PIP, etc.
Nevertheless, it worked well for a basic blog, I publish the articles directly in markdown format, embedding some HTML if necessary. In fact, all the pages are some sort of markdown, rendered to HTML upon loading. But of course, the URLs are not "real", I use the query string to refer to the pages, such as `mert.akeng.in/?/blog`, the JS fetches `/blog.md` and renders it to the `<main>` element. Much like how you would initialize React through/within JS.
The static site generators are nice, but it's really not a huge deal to spin up a few common css classes and maintain a little bit of mental discipline.
I think using a blog to communicate your ideas and skills is great. I think making the blog tech stack itself representative of those things seems distracting. Not everything has to be a smartass ego implementation. As long as you spend 5 minutes testing on mobile, your audience probably won't notice a damn thing the next time it touches the front page of HN or wherever.
I've built a blogging platform with similar vision which I could call "Minimum Viable Blogging Platform"
When I was experimenting with SSH apps I decided to create a blog platform inspired by it: https://prose.sh
Thanks for the inspiration!
I am moving (some of) my blog over now.
No category pages, no individual pages. No search... well, CMD+F is your search engine, and it's blazingly fast.
That design actually works really well if all you care about is getting text content out there, and the idea of comments—let alone ads—isn't appealing to you.
I'd like to try the same thing.
Is there a list of posts at the top or just H1s for each post?
Over the years I have added to my solution with custom markdown, tagging, rss, and most lately exif-stripping. Technically the source is available [0] but I can’t see anyone else using it.
Yes! I find the easiest way for me is to just open a new tab in my code editor and typing.
Exif is a real gotcha. I'm planning to compress images anyway, so this could be done in the same step.
Yeah, I thought I was being careful and manually stripping it from photos until a nice reader emailed me to gently let me know i had missed a few.
dirInfo, err := dir.Readdir(0)
if err != nil {
return nil, err
}
names := make([]string, len(dirInfo))
for i, fileInfo := range dirInfo {
names[i] = fileInfo.Name()
}
Edit: after looking more closely at sprig, the solve was sortAlpha
For whatever reason it's just not picking up themes even though I'm now using the most up to date everything. And actually I've realised I don't even like the vast majority of the themes anyway, including the one I used previously. And since developing my own hexo theme seems like kind of a faff, I'm pretty tempted to just throw together a Sass sheet, compile it to CSS, and use that as my theme.
I guess if I got into the detail of it - comments, archive pages, etc. - the complexity would start to creep in and I'd find that what I was doing was building my own home-rolled hexo-alike... so maybe I should persist with figuring out why themes aren't working for a bit longer.
The pre-rendering is just there to provide the surrounding page content when you create a new page.
html_content = html_content.replace('Minimum viable blog', title)
Did this originally say html_content = html_content.replace('{{ title }}', title)
And then you ran it?Sanitize your strings!
I have a question about this line of code
file_path = os.path.join(posts_dir, post_directory, 'eng.md'
Is eng.md an extra addition here? By looping through the directory, would the post names be found in the loop? By deleting this I was able to get the code to run and think I'll start using this as a blog template!
I've been thinking about using Obsidian as a static site generator.
It lets you create a blog and a newsletter with Markdown and publish directly from the command line (or the web editor). You get the offline-first workflow of Markdown, but with beautiful themes like substack.
It's like a mix between Wordpress, netlify and substack.
https://github.com/sareiodata/hx-weaver
That being said, I don't find myself actually writing a blog :)
I think I like simple.
Ping me on my work email and I’ll send you some fun links! :)
As easy as wordpress, square space or whatever claim to be, in my mind this is even easier, the solution is more elegant, and you expose yourself to a whole lot less crap along the way.
Edit: I recognise this doesn't cover hosting, domain registration etc.
It really does help when you don’t even have the potential option to distract yourself with bells and whistles.
Write some markdown, run a command and your blog updates.
Mobile screens and desktop are fundamentally different. You can’t have small and big at the same time.
That is solved via the standard html img srcset
Astro solves that easily.
And Wordpress of course.
You don't need a backend.
For all of them I built Lykhari.com
Are there anything like ghpages with a built in wysiwyg editor?
Also, etherpad can export to html.
The nice thing about latter is that the bandwidth, DDoS or other load-related issues aren't that much of a problem. Server maintenance also isn't a problem as you don't have any.
For serving static files, I can (and have) lived a long time with one of the "free hoster" sites -- from times before Github Pages or S3 were a thing I guess, today I'd go for Github Pages.
A key advantage of moving to an own server was that I can enable the odd feature or technology any time. E.g. most recently I wanted to have some "private" subspace with fancy authentication and it was easy to add with proper access to the server config.
I think you're overestimating the work required to put together a web server. For example, you mention dumping files in a S3 bucket, but that doesn't require much more work than whipping out a nginx instance and dropping said files in a folder.
Also, some people already run their own servers or deploy their services in some cloud procider. The work required to put together a blog is minimal.
It's not necessary. Just a fun thing to do.
I think even SEO is on the outs in favor of established domain authority, so the best tactic is to blog expecting obscurity.
Millions of sites use WP and there are configurations to mitigate this. Some caching and easy server config will be enough to survive the “hug”
WordPress handles volume just fine. Nothing a HN hug would disrupt.
WordPress is used at scale by many companies.
Better is use a static site plugin, then you don't have to bother with configuring any caching or external services.
Best is also use the SQLite Database Integration plugin, so the server doesn't even have to run MySQL/MariaDB (other than initial installation), and on an otherwise light server, the filesystem will effectively keep the site in page cache while using less memory, if I understand that correctly.
The WordPress interface can be kept behind HTTP auth or client cert.
Several WordPress caching plugins, like W3TC (https://wordpress.org/plugins/w3-total-cache/), actually add rules to your Apache/Nginx server so that the cached HTML pages are served statically without touching PHP.