It's been a fun two weeks trying to reinvent the personal blog wheel in a decentralised way.
So far I've:
- designed an architecture for journal,
- selected libraries and frameworks for the job,
- and created the first two pages of journal.
At the moment, I've gotten as far as populating journal with random data to test-drive the aesthetics with a focus on ensuring the view is responsive to different media sizes.
A few of these updates made it to twitter icymi:
Here's the story so far.
The architecture was created with the key features in mind. These are:
- instant loading of articles,
- compatibility with web-crawlers for search engines and previews on social media sites,
- being able to link to a particular article.
All of these are enabled through a web server that renders content server-side. Creating an architecture that allows for SSR whilst preserving the decentralisation of the data is not impossible, but slightly tricky.
Ultimately, the article and user data will be stored in a decentralised store, backed by matrix. One SDK in particular is closest to being able to access the entire feature set of matrix protocol and is one that I am very familiar with - the matrix-js-sdk.
With this in mind I hatched a plan to wrap matrix with this SDK behind a journal-specific backend that will act as a matrix client. It will act on behalf of a special user that can access all public blogs (on the same matrix homeserver or otherwise) but the mechanism for this remains unclear and I'm still contemplating it.
When a user interacts with journal in a way that must be authorised, they will run a matrix-js-sdk-backed matrix client in their browser. This will allow them to make requests directly to the matrix server (not via the journal backend) logged-in as their desired user. This enables them to post blogs, send comments and subscribe to others' blogs.
When talking to my girlfriend about the way she uses blog sites, she made it clear that she would expect to be able to subscribe to a user's blog.
Features like this require an asymmetrical "reading/writing" API via matrix and a "reading" API via the journal backend. This could be difficult to maintain as an architecture but at least separates the public data exposed by the journal backend from the private data exposed directly by the matrix backend.
Despite being authenticated as a matrix user, it would still be beneficial to access blog lists and blog posts rendered server-side as opposed to accessing them directly on matrix.
One option for React-based SSR is Zeit's Next.js. It provides a framework for developing a React app that can be rendered server-side but also support dynamic client-side updates. Below is a diagram showing how it fits in to the architecture.
(3) journal backend-----[matrix] | | | (2) | | ________| (4) | | | | | | next.js ____|__:________|_________ | | | journal web UI frontend | |__________________________| | : (1) | |(2) | | web browser
Figure 1 shows how next.js fits into the architecture of journal, encapsulating the web frontend that the browser communicates with.
- Web browser and next.js backend make requests for data
- journal backend makes requests for public matrix data (journal bot)
- next.js backend makes authenticated matrix requests
With this in hand, I decided to finally start writing the view for journal based on designs I sketched a few months ago. The results are promising; see the tweets at the beginning of the article.
Next up is user authentication/registration and after that, blog creation and commenting. All of this is still strictly in the frontend, the next step will be to implement an API for the journal backend, probably using GraphQL.
Anyway, that's all for now. Any questions? Feel free to leave a comment.
Follow me for more updates 🚀