Announcing Nitropage

The concept behind Nitropage and the way forward.

Katja Lutz

Web Developer

Announcements
04.03.2024
This is a follow up to the earlier German announcement which you can find here. Today I want to give a more detailed, technical look on my thoughts behind Nitropage - this time for my English fellows :D.

Do we really need another CMS?

We have a very wide range of different ways to build websites, from traditional CMSes like Wordpress, TYPO3 and Drupal, over headless ones like Directus and Payload, to builder-centric ones like Wix, Squarespace and Weebly. Some of us even completely skip the CMS for a file-based (Markdown) approach, generate static websites with tools such as Astro, Quartz or write the whole HTML by hand. Most of these solutions attract specific roles:Traditional CMS: Users can directly adapt and extend the CMS with click-installable themes and plugins, without coding-skills. As a developer and maintainer you either fully acclaim the freedom of the users and become urged to install third-party plugins, that the users can later customize without your help, often resulting in a very unmaintainable website. Or you instead fight against the CMS and disable half of the options and the plugin manager. At the end of the day you are left with a CMS that just isn't really focused on developer experience."Freemium" Builder CMS: Users have even more control than with a traditional CMS. Developers on the other hand are usually completely out of the picture - you just have to accept the limitations of the CMS.Headless CMS: Developers have full control and can extend the website freely with their coding-skills. The development is usually faster than with a traditional CMS, but then again they also have to write more code, because the frontend is completely custom. With so much power in the hands of the developers, this often comes at the price of less-freedom for users.With Nitropage I want to share a fully Open-Source solution, that strives to connect the web desires of users and developers. My thought was: why not a CMS with an opinionated yet developer friendly frontend stack, that helps developers to get shit done with code instead of Klickibunti third-party plugins, but that also comes with a tightly integrated, nifty drag-and-drop page editor for the users? Well to be fair, I am not the only one with this idea, thinking of products like Builder.io, Bubble and React Bricks - but those are not Open-Source projects.All of that said, every solution has its tradeoffs, Nitropage included. It does not have replaceable themes or plugins that can be installed with a single click. At the time of writing there is also no special functionality for blogging. You wanna write a blog post? Create a page that looks like a blog post and set the option to include it in the RSS feed. Wanna create another blog post? Just duplicate the previous one and make your changes. The goal is to have answers for the common problems and give developers the tools to frictionless solve the uncommon ones.
Nitropage tries to fill the gap between Headless and Traditional CMSes
Thanks to a very modern stack, the developer can change parts of the design and instantly see the result (hot module replacement). This even applies to Settings, e.g. if the developer adds a new "color" Setting (left side), it instantly appears in the Page Editor (right side):

Blueprints, Elements and Settings

So Nitropage doesn't have exchangeable themes like a traditional CMS. Instead the website is fundamentally built around composable Elements, think of them like lego bricks. And like lego bricks these Elements also come in different shapes. We call these shapes Blueprints and they are predefined by developers. As an example, imagine a "Button" Blueprint, defining the shape and functionality for all buttons on the website. But on a real website you don't always want to show the same button, you usually want to change the text, colors, size, etc. - thats where Settings come into play. Let's try to distil this all down a bit:
  • Blueprint: Reusable recipe for the shape and functionality of a specific idea.
  • Element: An actual "cooked" representation of that idea.
  • Setting: Modifiable details of the Element.
One important aspect of these Settings is that their values can be accessed in the Blueprint Component with proper typings by default, that is if the code editor is supporting TypeScript ;). Such a Blueprint can be a single file including everything that is needed to define the shape of the Element and its possible Settings. Check out this little example, if you are a developer:
import { createBlueprint, BlueprintComponent } from "nitropage";
import { textData } from "nitropage/data/text";

// How the blueprint should be rendered, literally a Solid Component
const MyComponent: BlueprintComponent<typeof blueprint> = function (props) {
  return (
    <div {...props.elementProps}>
      {/* Used to show selection borders in the Page Editor */}
      {props.handles}

      {/* Accessing the "title" / "text" setting value, props.data is properly typed */}
      <h2>{props.data.title}</h2>
      <p>{props.data.text}</p>
    </div>
  );
};

// How the blueprint should behave in the Page Editor
export const blueprint = createBlueprint(
  () => ({
    // Schema for the available Settings
    data: {
      // textData can be used for "string" values
      // it will render a simple input field in the Element Editor
      title: textData(),
      // Another "string" value, with a wider input field
      text: textData({
        wide: true,
      }),
    },
  }),
  import.meta.hot
);

export default MyComponent;
// Every blueprint must have an unique identifier
// The blueprint file can be freely renamed or moved, Elements on the page will work regardless
export const id = "lxu9qu296xliwwqoyurgkrv3";

Settings Inheritance and Presets

Now assume that you create a website with multiple pages, each having multiple buttons and you wanna set the color of all buttons to blue. As a developer you would just open the "Button" Blueprint and change the color in the code. But as a user you would have to open all pages and go through all buttons, changing their colors one after the other. Wouldn't it be dope if you could set a default color for all buttons, for the whole website? Well in Nitropage you can! Moreover you can create Presets overriding the project defaults. Each Setting has three layers which optionally override each other by priority: 1. Element ⬅️ 2. Preset ⬅️ 3. Project
A diagram explaining how elements inherit their Settings
Let me demonstrate to you how this looks like in the actual editor:
This inheritance layer is built-in, every Setting gets it automatically and the developer doesn't have to think about it, giving them more time to work on significant changes. There already exists a wide range of setting types, from Toggles, Colors, Fonts, Richtext, Dropdowns to Lists (arrays) that can include nested Settings and many more. The developer can also create custom setting types using their own components. All of this is powered by Solid Signals. They automatically keep the Page Preview (left) and the Editor Sidebar (right) in sync, as unobtrusive and smoothly as possible.

Technology

Instead of hiding away the underlying technology, Nitropage gives the developer direct access to it. The developer can use this opinionated, yet highly flexible stack, to implement custom business logic. Imagine the need to sell products on a Nitropage based website: in such a use-case the developer can literally extend the database schema, access their custom products data via Server Functions and serve the shop via a Route independently from Nitropage or via shop-specific Nitropage blueprints.Blueprints essentially are Solid Components coupled with Nitropage Settings. It's up to the developer if and how they wanna couple a Solid Component to Nitropage. This opens up an important migration path towards or away from Nitropage, in either way letting the developer reuse their existing Solid code.Opening up the framework that much to the developer also has its tradeoffs: Nitropage probably will never have automatic updates like Wordpress, therefore the maintenance of a Nitropage project is fully dependent on developer skills. Personally I think this is fine because most projects fall into one of these categories:
  • Throw-away landing pages and experiments: No need to do huge software upgrades anyway, better start new projects on a fresh basis.
  • Up-to-date sites with constant changes: These should be regularly maintained by developers.
By following this approach, what we end up with are clear roles for users and developers:
  • Users: Create and design pages, write content, organize projects (one Nitropage instance can serve multiple websites).
  • Developers: Create and extend blueprints, maintain the codebase, update and deploy the Nitropage instance.
Overview of the Architecture

Performance & SEO

As already mentioned, Nitropage is based on Solid, a very fast frontend library that is focused on highly interactive Web Applications. Because of this Blueprints likewise can be highly interactive. However: Interactivity overall increases loading times and reduces performance, therefore Nitropage websites can never be as fast as highly-opimized fully static websites. We still take performance very seriously and optimize where it makes sense. Pages only load the code they need. Blueprint Components are lazy loaded and can be rendered passively, disabling their interactivity and client-side hydration.Pages are rendered on the server first, even with the interactive Elements in their initial state, therefore the page content can easily be crawled by search machines. This also greatly reduces content jumping and flashes of unstyled content, that you often can see on traditional-CMS based websites.

Freedom of speech

I didn't only create Nitropage to innovate the way we make websites, I wanted to share a tool that helps in the fight against online censorship specifically regarding individual websites. If you want to say what you think in social networks, you can join a decentralized one, but if you wanna create an own public website, it's gonna depend on one central provider (yes, even if you do self hosting), and if this provider doesn't like what you say and has political/financial incentives, well... hard luck for you. The only way around this is, to make it as easy as possible to move to a different provider. Nitropage helps with this by being fully Open-Source and by internally using tools that simplify deployments to different providers. That's also the reason why there is no hosted "premium" plan for Nitropage. We rather should work on making the deployment process as smooth as possible, instead of creating another proprietary hosting service for Nitropage that binds its users to it.

Road to v1.0

A detailed roadmap can be found here. Apart from a lot of work on the documentation, the major blocker for v1.0 is the migration to the current SolidStart Beta: Nitropage was built with the old SolidStart Beta 1 and still is based on it. The recently released SolidStart Beta 2 included several breaking changes, completely incompatible with Nitropage. For the moment I am taking a break from further changes to Nitropage and I will observe the development progress of the new SolidStart Beta. I likely will wait with the migration until SolidStart is stable enough and has all the functionality internally required by Nitropage. The migration will require a heavy rework of many internal systems and sadly also comes with breaking changes in public APIs, specifically the Image Optimization API used by most Blueprints. I am also using this intermission to look back at past decisions and to try out lighter alternatives to SolidStart, which might simplify the migration.

Funding

One of my deepest, idealist wishes is that the web stays a free place where fearless humans can share their ideas and maverick artists can show their masterpieces. But over the years I noticed how the web became more and more a digital copy of our commercialized consumer society, Art became Content, Character became Uniformity and ~Freedom of speech~ became ~Better safe than sorry~. Nitropage does not follow this trend and will always be a fully Open-Source project without features locked behind paywalls or premium plugins. It lives from voluntary donations and will only be sustainable in the long run, if the web community notices its value, despite the missing price tag.

Getting started

There currently exist three ways how you can try out Nitropage:
  1. Check out the Page Editor via the Playground
  2. Install Nitropage locally by following the Getting Started guide
  3. Directly deploy Nitropage via Cloudmos / Akash. A huge thanks to Patrick Balsiger who took the initiative and implemented this deployment 💪🏻!

Join the community

You are very welcome to join the official #nitropage channel in the Solid Discord or to join the Lufrai Community Forum. I would love to see you there, chat about this blog post, answer questions and guide you through the project.