Hello, Ordinary Blog

seanwatters1 pts0 comments

Hello, Ordinary Blog :: Ordinary BlogHello, Ordinary Blog<br>2026-05-26sean 🐘 🏔️<br>#blog  #ssg  #hugo  Having spent a bit of time now working with Ordinary to run my personal blog, I wanted to set up a more formal facility for posting about the framework itself.Ordinary has always been designed with the idea that it should be as (or more) straightforward to run your own space on the web as it is to set up an ActivityPub account – so, for that reason, I picked to build its blog with the highest barrier-to-entry SSG that also seemed reasonably popular: hi, Hugo.Context#<br>I started work on Ordinary in earnest just over a year ago. at a high level it’s a supposed to be a multi-site CMS, with room to grow. The initial focus has been on being a really solid web-server and serving primarily static content, but with the long-term focus being on enhancing and extending the static content with plugin/module/etc.-like units that can hook into the underlying storage mechanisms and call out to external services.For this post, we’re gonna stay very narrowly focused on the Ordinary’s concept of assets (and won’t even get into templates/content; Ordinary’s “native” tooling for managing content).Goal#<br>Generate a static blog from Markdown files, with an RSS feed, that can be updated and deployed to api.ordinary.host with minimal friction.Process#<br>Hugo was new to me – I’ve built SSGs with Jekyll, SvelteKit, Nuxt and others I won’t mention – but getting installed and started wasn’t too bad once I landed on the theme I actually wanted to use (terminal by panr seemed like the most fun).Because I already have ordinary CLI and all its deps installed, I didn’t have to do anything special. Right now building from source is the best way to make sure you’re compatible with the Ordinary API Server (if you’d like to install and break stuff: instructions).Hugo (generate)#<br>After installing the Hugo CLI installed and initializing a project, it took me a bit to tune the terminal theme and override some of the defaults to get to a spot where I was happy with the archetypes/, layouts/, static/ and RSS feed, but it works for now.I also had to make some tweaks to get things working with Ordinary by adding a [params].canonical = 'https://oridnary.blog' to the hugo.toml and then set the baseURL to '/' instead of the real domain1.A quick run of$ hugo build

will output the generated site to public/. And now we have something to deploy to somewhere.Ordinary (build && publish)#<br>Enter: ordinary ssg init…Note: when I first built it out, I wrote out all of the ordinary.json config by hand, but have since added the ordinary ssg init convenience function so that you don’t have to!<br>$ ordinary ssg init --help<br>generate an `ordinary.json` config to deploy your SSG to a running instance of `ordinaryd`

Usage: ordinary ssg init [OPTIONS]

Arguments:<br>project domain<br>assets `dir_path`

Options:<br>-c, --contacts ... contacts for Let's Encrypt (auto-TLS)<br>-e, --error-page include 404.html as error page<br>-s, --inline-styles accommodate inline styles in the generated files<br>-r, --inline-scripts accommodate inline scripts in the generated files<br>-m, --inline-images accommodate inline images in the generated files<br>-p, --project project path [default: .]

-v, --verbose... Increase logging verbosity<br>-q, --quiet... Decrease logging verbosity

-h, --help Print help<br>-V, --version Print version

Constructing the command for our Hugo project is pretty straightforward; we know that our theme generates a 404.html in the public/ generated output, so we’ll include -e2. We also know that our theme uses inline styles in some places, so we’ll add the -s flag in our command. Because the server we’re deploying to has --insecure disabled, it will use the rustls-acme crate to automatically generate TLS certs with Let’s Encrypt, so we also need to include at least one contact email address to be sent as a part of that process: -c support@ordinarylabs.io. The domain is obviously ordinary.blog and the Hugo generated dir is public so our command looks like this:$ ordinary ssg init ordinary.blob public -c support@ordinarylabs.io -e -s

And that produces the following ordinary.json file:// oridnary.json<br>"domain": "ordinary.blob",<br>"contacts": [<br>"support@ordinarylabs.io"<br>],<br>"version": "0.1.0",<br>"storage_size": 10000000,<br>"port": 4433,<br>"error": {<br>"asset": "404.html"<br>},<br>"assets": {<br>"dir_path": "public",<br>"base_route": "/",<br>"append_index_html": true,<br>"html_csp": {<br>"style_src": "'self' 'unsafe-inline'"<br>},<br>"http": {<br>"cache_control": {<br>"max_age": 3600<br>},<br>"expires": 3600<br>},<br>"precompression": [<br>"All"<br>],<br>"minify_html": true

Breaking this down:"domain" tells ordinaryd how to route requests based on the SNI and host headers (if "cnames" were set those would also be used)"contacts" are sent to Let’s Encrypt as a necessary component of getting a cert issued by them"version" is the version of this project’s ordinary.json and should be incremented when breaking changes are made"storage_size" tells ordinaryd to set this...

ordinary blog hugo inline project generated

Related Articles