Using Nuxt Layers to create a theme system - Build in Public #3

By Hugo LassiègeMar 12, 20244 min read

For the blog platform Bloggr, one of the features I felt was necessary to really be a blog platform was the theme mechanism. There's no such thing as a blog platform without it.

If people like Wordpress, or Ghost, it's because there are loads of themes (and plugins) available to enable them to make their own blog. Each template has its own configurations that allow them to make it unique.

And if I want to offer a similar experience, I have to create this mechanism.

Using nuxt layers

Nuxt has two very interesting extension mechanisms, modules, and layers.

Honestly, the difference between the two is quite subtle. And if you know the difference, well, there's someone on Stack Overflow who's still waiting for the answer :)

I know how to use both, but I wouldn't know what the criteria would be for choosing one or the other. For a theme, I found it quite natural to use the layers mechanism. But that's more intuition than anything else. And also because I didn't want to go to the trouble of publishing my code on npm :)

My goal is to make it as easy as possible to install a theme in nuxt.config.ts

export default defineNuxtConfig({
    ...
    extends: [
        "github:hlassiege/bloggr#main", // extends the bloggr engine
        "github:hlassiege/bloggr-epoxia#main", // extends the theme for epoxia
    ],
...
})

And activate it in app.config.ts

export default defineAppConfig({
    theme: "epoxia",
})

That's exactly how it works.

To give you a general idea of what a layer is on nuxt. Let's say it's as if your project had a set of files that were transparently added to yours.

This line :

    extends: [
        "github:hlassiege/bloggr-mistral#main", // extends the theme for mistral
    ],

means that it's as if you had the contents of the bloggr-mistral repository directories (https://github.com/hlassiege/bloggr-mistral) included in your project. All components and layouts are automatically available. You can also specify whether you want a particular version, as this theme may be compatible with a specific version of bloggr. So you could write :

    extends: [
        "github:hlassiege/bloggr-mistral#1.0.0", // extends the theme for mistral
    ],

Limitation(s)

At the moment, I have one limitation. Although it's super convenient, the assets and public directories are not affected by the extension mechanism. So, it's impossible to have assets, images or fonts by default.

I think it's possible to solve this problem with mixing modules and layers and putting a module in the layer that forces you to add a few files.
But I haven't tested this yet.

How do I make a private theme?

I'm not hiding the fact that I have an idea behind this. Bloggr works well, I use it for my English blog and my French blog.

I think offering Bloggr as open source makes sense and I can't imagine doing otherwise. Especially since it's 95% built on Nuxt and nuxt-content. On the other hand, I'm thinking that offering paid themes for Bloggr could be interesting.
It's exactly the same principle as taking on paid themes for Wordpress and Ghost.

So I've come up with a free theme, called Mistral.
And then I developed a paid theme: Epoxia.

Both can be seen on the theme gallery on the site.

What's more, I think it's fun to practice web integration and I'm thinking of proposing others.

For the moment, to be honest, the result is 0 sales ^^ But hey... I'm still straddling the line between side product for fun and product, so it doesn't matter.

To share my questions with you, though, I'm still a bit lukewarm on Epoxia's distribution method.

Adding Mistral is as simple as this:

export default defineNuxtConfig({
    ...
    extends: [
        "github:hlassiege/bloggr#main", // extends the bloggr engine
        "github:hlassiege/bloggr-mistral#main", // extends the theme for mistral
    ],
...
})

Adding Epoxia can work the same way, but it's a private repo. So, I have to give a github token to put in environment variable to let you use the same syntax. That's what I do for my two blogs. A bit tricky if I want to provide one token per person.

Or, as I'm doing at the moment, I take the zip from the repo and upload it on Buymeacoffee but it's really impractical and the theme is never up to date.

I admit I'm hesitant. I've seen other examples on the net:

  • the repo remains open. It depends on people's probity to respect the license (?)
  • the code is put on npm, and you can include it, but you need an activation key to generate the static site (that's the nuxt-ui-pro approach).

In both cases, since the code is public, it's as if it were open source. But it seems to work. There must be people taking advantage of the system, but it seems acceptable.

I haven't made up my mind yet. And it's a non-issue as long as nobody takes the template anyway.

And if you're interested, current bloggr traffic is around 200 unique visitors a week, more than half of whom also visit the two demo sites.

Current traffic - analytics dashboard
Current traffic - analytics dashboard

bye


Share this:

Written by Hugo Lassiège

Software Engineer with more than 20 years of experience. I love to share about technologies and startups

Copyright © 2024
 Eventuallymaking
  Powered by Bloggrify