Tayzen's Blog

Smallblog, update 1.3!

I released the previous version of smallblog in december, after some feedbacks I made some (I hope welcome) changes! In the changelog: new theme, file-based routing, new configuration and fixes to the RSS rendering.

New theme

First, I made a bright theme. A feature I wanted to make before the first public release but I've not invested enough time into it. A new button is available in the top right corner of the screen to switch between themes. You can try it yourself or just look at this is a screenshot:

Bright theme screenshot

The theme is automatically selected from your browser/desktop settings!

Warning

The theme switching is entirely dependent of JS, if you have no JS enabled in your browser you will only have access to the dark theme. This behaviour will probably be changed in future releases.

Technical details

This is a quick technical overview, I will create a separated blog post for more details.

To create the theme I first chose a color palette using different services to get inspiration (pinterest, colors from adobe, coolors.com and realtime colors).

Once the color palette chosen, I had to edit the CSS file. It was a messy process because I hadn't well organized the theme before, colors were everywhere in the CSS rules. So, I listed everything, tried to make logical groups and then created variables to have everything well organized. If you don't know, you can define CSS variables like so: --color-table-header: #ffb13e and use them this way: background-color: var(--color-table-header). This enables you to set all your colors in the same place and if a color is used many times, you can easily edit one line to change everything.

The third step was defining the light theme in CSS. For that, I use the following CSS selector: [data-color-mode="light"]. Then in this selector I edited the colors of the CSS variables. I also added the following CSS selector [data-color-mode="dark"] to set the colors of the dark theme.

Finally, I added a button to switch between the themes, which triggers a JS function to switch the data-color-mode property of the body. This code also set the default value of the data-color-mode property to the theme used by your browser. If you manually change the settings, the chosen theme is stored in the local storage of your browser, so changing page doesn't reset your preference.

File-based routing

In the previous version, you could only define blog posts or pages available from the navbar. This behaviour was enough for the vast majority of cases, but the new design enables you to have so much freedom.

The file-based routing is a feature asked by pomdtr, the developer of Smallweb. It is used by some SSG (static sites generators) like vitepress. The idea behind this kind of design is to be as intuitive as possible, you create a page in your filesystem, it is available at the corresponding route.

In our case, with this new feature, the pages creations are way less limited. If you want to create a page which is shared only in an article, you can! You want to set up an Easter egg only available from a specific URL, you can!

And if you want to set up a new page in your navbar, this is still possible!

Technical details

I use Hono to route requests, before the change for file-based routing, I had 4 main ways to handle requests:

  1. The special resources (/robots.txt, sitemap.xml, favicon.ico, ...)
  2. The root (/), where you can see the list of posts
  3. The posts (/posts/...)
  4. The other pages or static files (/...)

The file-based routing enables me to handle the last two types of requests the same way. This is :

server.get("/:filename{.+$}", (c) => {
  // Extracting the resource name from the route
  const filename = c.req.param("filename");

  if (!filename) {
    // This is the root, this shouldn't be handle here
    // Returns a 404 error but should never be reached
    return serveError(404);
  }
  if (path.extname(filename)) {
    // The articles doesn't have extensions
    // Returns the corresponding file (often images)
    return serveStaticFile(filename);
  }

  // Splitting the resource name between the folder and the file
  const basename = path.basename(filename);
  const dirname = path.dirname(filename);

  // Serving the page (the posts are handled differently than the other
  // pages by the function, this is why we extracted the dirname before)
  return servePage(
    dirname,
    basename,
    // Other parameters...
  );
});

The route parameter /:filename{.+$} can be difficult to understand. It simply means: "extract a filename variable from the route (:filename), it should contain any characters (.+) after / until the end $".

As I changed the routing, the old way to set up the links in the navbar is not possible anymore. Moreover, adding an external URL and changing the order of the link was done with metadata, that was clunky. Now, this is much more comprehensible, you create your pages as you want and to set up the links, you edit the config as followed:

export default new Smallblog({
  // the other parameters
  navbar: [
    {
      name: "Contact",
      path: "/contact",
    },
    {
      name: "Github",
      path: "https://github.com/tayzendev/smallblog",
    },
  ],
  // ...
});

The order in the navbar is defined by the order in the list, the names properties correspond to the text displayed, and the path is the URL. I think this design is quite easy to understand and avoid weird metadata manipulations.

Fix of the RSS feed

The RSS feed was broken for most clients, I fixed it!

Technical details

The issue was the content of the article, the entire HTML content was included in the summary, so most clients displayed the posts as raw HTML. To fix that, I only extracted the description of the post in the summary and I moved all the HTML content inside the property content:encoded.

Some elements were also not rendered correctly in some readers, so I had to make other changes:

  1. No more SVG are used in the RSS feed (there were SVG next to each titles, and in the alerts)
  2. The YouTube videos are not displayed as iframe but as a link to the video. The iframe was not rendered at all on some clients I tested which was not a great experience.
  3. The mermaid diagrams are just displayed as code, as they do if no JS is enabled on the client. This is because JS injection is not possible in most RSS readers (hopefully in most cases)

Update procedure

If you are already running an instance of smallblog, you just have to follow these few steps and you will be good to go:

  1. Update your import jsr:@tayzendev/smallblog@1.2.0 → jsr:@tayzendev/smallblog@1.3.1
  2. Remove the parameter: pagesFolder
  3. Add the parameter: dataFolder if you don't want to use the default value data/
  4. The parameter postsFolder is relative to the dataFolder, if you don't want to use the default value posts (which corresponds to path ./data/posts), you should modify the value accordingly
  5. If you had custom links in your navbar, you should move the markdown files out of the pagesFolder, remove files corresponding to external links, add the navbar section in your config as shown in the previous section.
  6. Save your files, everything is updated!

If the migration process is not working, don't hesitate to open an issue on GitHub.