Skip to main content

Β· 12 min read

CMSs

If you are working on any kind of public-facing digital project β€”no matter if it's a website, a web app, a mobile app or desktop app β€” you will likely need a Content Management System. There are a lot of options to chose from, and different solutions are better suited for some needs than others. We can distinguish some categories straight away:

  • General purpose or web oriented
  • Headless or traditional
  • By access to data APIs (GraphQL, REST, SDKs)
  • Cloud based or self-hosted

We are building this guide to help you pick the right CMS for your project. We will be updating it regularly, so make sure to check back often.

One of the motivations for this guide is to help users understand the differences between CMSs. Despite creating FireCMS, we are not trying to promote it as the best solution for everyone. We are just trying to help people understand the trade-offs of different solutions. This is the same thing we say to our users when they ask us for advice on what solution to use.

General purpose or web oriented​

The first thing to consider is whether you need a general purpose CMS or a web-oriented one. A general purpose CMS is a tool that can be used to manage content for any kind of project (apps, desktop, web), while a web-oriented CMS is a tool that is designed to manage content for websites.

Web oriented CMSs are built with the assumption that the content will be displayed on a website, and they usually provide a web editor to edit the content. This is not the case for general purpose CMSs, which can be used to manage content for any kind of project, including mobile apps, desktop apps, etc.

Web oriented CMSs are usually simpler to use, but they are also more limited in terms of features and integrations. They provide built-in support for pages, headers, footers, navigation menus, and other common website features, but they are not as flexible as general purpose CMSs. Also, they will typically have a published flag (or equivalent) for each entity. Of course, nothing stops you from using a general purpose CMS to manage content for a website.

Do you need a blog? A web-oriented CMS will likely have a built-in blog solution, while a general purpose CMS will not.

Examples of web-oriented CMSs are Wordpress, Prismic or Storyblok. Those are the way to go if your main goal is to build a website and a web editor is useful to you.

General purpose CMSs can be used to manage any type of content. Think of things like the menu of a restaurant or a delivery app. Or the exercises and videos of a fitness app. Or the podcasts in a podcast app. If you are working on a mobile app or a web app where you need to manage any content related to your business, FireCMS is a great option. It has all the advantages of other general purpose CMSs, but it uses Firebase as a backend, so you have access to all the robustness, extensibility and features of Google Cloud.

Headless or traditional​

Traditional CMSs are the ones that provide a web editor to edit the content, and they will be responsible for rendering it on the website. So the admin interface and the website are tightly coupled.

Headless CMSs are the opposite: they are not coupled to the rendering of the website and are in charge of managing the content exclusively. CMS and website are different software components in this case. They provide an API to access the content. The website is responsible for rendering the content, and it can be built with any technology.

Headless CMSs are more flexible than traditional CMSs, but they require more work to build the website. The benefit is that you can build it with any technology you want.

Note that a CMS can be web-oriented and headless at the same time. In this case, the CMS will provide a web editor to edit the content, but it will not be responsible for rendering it on the website. Examples of this are Prismic, Contentful or Agility CMS.

Examples of headless and general purpose CMSs are Strapi, GraphCMS or Sanity

FireCMS is a headless and general purpose CMS. It is a general purpose CMS that can be used to manage content for any kind of project, including websites, web apps, mobile apps, desktop apps, etc.

Access to data APIs​

The next thing to consider is the APIs provided by the CMS. The most common APIs are REST and GraphQL. REST APIs are the most common, but they are not as flexible as GraphQL APIs. GraphQL APIs are more flexible, but they are a bit harder to use.

Some CMSs provide SDKs to make it easier to use their APIs. SDKs are usually available for the most common languages, like JavaScript, Java, Python, PHP, etc.

FireCMS uses Firestore as a backend, so it benefits from all the native SDKs provided by Google. This is a big advantage, because it means that you can use the same SDKs to access the CMS and to access the Firestore database. At the same time, having Firebase as a backend means that you can use all the Firebase features, like authentication, hosting, functions, etc. No other CMS can offer this.

Cloud based or self-hosted​

The last thing to consider is whether you want a cloud based CMS or a self-hosted one. Cloud based CMSs are hosted by the CMS provider, and you don't need to worry about hosting and maintenance. Self-hosted CMSs are installed on your own servers, and have a little more overhead, but also better flexibility.

Other considerations​

Main user type​

If your main user type is a content editor, you should consider a CMS that allows them to edit the content without having to write code. Also, you want to make sure that the CMS is easy to use, and that it provides a good user experience, as well as preventing users from making mistakes, that could potentially break the apps linked to the underlying database.

Data portability​

If you are planning to use a CMS for a long time, you should consider the data portability. You want to make sure that you can easily export the data from the CMS, and that you can easily import it in another CMS.

Also, you want to check the license of the CMS. Some CMSs are open source, while others are proprietary.

CMSs comparison​

Check the comparison table below to see which APIs are provided by each CMS.

NAMEFireCMSAgility CMSButterCMSContentfulGhostGraphCMSKeystone JSPrismicSanityStoryblokStrapiWordpress - unite cms
Installation
Open Sourceβœ…βŒβŒβŒβœ…βŒβœ…βŒβœ…βŒβœ…βœ…
Cloud ServiceWIPβœ…βœ…βœ…βœ…βœ…βŒβœ…βœ…βœ…βŒβœ…
On Premises Installationβœ…βŒβŒβŒβœ…βŒβŒβŒβŒβœ…βœ…βœ…
Cloud Service Hosted in Europeβœ…βŒ~❌~βœ…βŒ~βœ…βœ…~βœ…
Commercial Support Available?βœ…βœ…βœ…βœ…βœ…βœ…βŒβœ…βœ…βœ…βœ…βœ…
Users
User Managementβœ…βœ…βŒβŒβŒβŒβœ…βŒβœ…βœ…βœ…βŒ
Role Based Permissionsβœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…
Document Level Permissionsβœ…βœ…βŒβŒβŒβŒβœ…βŒβœ…βœ…βœ…βœ…
Features
Web builderβŒβŒβŒβŒβœ…βŒβŒβœ…βŒβœ…βŒβœ…
Real time supportβœ…βŒβŒβŒβŒβŒβŒβŒβŒβŒβŒβŒ
Search: Full Text Searchβœ…βœ…βœ…βœ…~βœ…βŒβœ…βœ…βœ…βœ…~
Eventbusβœ…~❌❌~βŒβŒβŒβœ…βœ…βŒβŒ
Client Side Formsβœ…βœ…βŒβŒ~βœ…βœ…βŒβœ…βŒβœ…βŒ
Plugin Systemβœ…βœ…βŒβŒβŒβŒβœ…βŒβœ…βœ…βœ…βŒ
Customizable UIβœ…βœ…βŒβœ…~βŒβœ…βŒβœ…βœ…βœ…βœ…
Content Treesβœ…βœ…βŒβŒ~βŒβŒβŒβŒβœ…βŒ~
Nesting fields/elementsβœ…βœ…βœ…βœ…~βŒβŒβœ…βœ…βœ…βœ…
Image: Manipulationβœ…βœ…βœ…βœ…~βœ…βœ…βœ…βœ…βœ…~
Technical
OAuth 2.0 Supportβœ…βœ…βŒβœ…~βŒβœ…βŒβœ…βœ…βœ…~
CDN Supportβœ…βœ…βœ…βœ…~βœ…βŒβœ…βœ…βœ…βœ…βœ…
Backup Featureβœ…~❌❌~βœ…βŒβŒβŒβœ…βŒβŒ
Import/Exportβœ…βœ…βœ…βœ…~βœ…βœ…βœ…βœ…βœ…βŒβœ…
CLIβŒβŒβŒβœ…βœ…βŒβœ…βœ…βœ…βœ…βœ…βœ…
Web Hooksβœ…βœ…βœ…βœ…βœ…βœ…βŒβœ…βœ…βœ…βœ…βœ…
Versioningβœ…βœ…βŒβœ…βŒβŒβŒβœ…βœ…βœ…βŒβœ…
Data
GraphQL: APIβŒβœ…βœ…βœ…βŒβœ…βœ…βœ…βœ…βœ…βœ…βœ…
REST: APIβœ…βœ…βœ…βœ…βœ…βœ…βŒβœ…βœ…βœ…βœ…βœ…
SDK: Javaβœ…βŒβŒβœ…~βŒβŒβœ…βŒβœ…βŒβŒ
SDK: C#βœ…βœ…βœ…βœ…~βŒβŒβœ…βœ…βŒβŒβŒ
SDK: PHPβœ…βŒβœ…βœ…~βŒβŒβœ…βœ…βœ…βŒβŒ
SDK: JavaScriptβœ…βœ…βœ…βœ…βœ…βœ…βŒβœ…βœ…βœ…βœ…βŒ
SDK: Reactβœ…βœ…βœ…βŒ~βœ…βŒβŒβœ…βœ…βŒβŒ
SDK: AngularJSβœ…βŒβœ…βŒ~βœ…βŒβŒβŒβœ…βŒβŒ
SDK: TypeScriptβœ…βŒβŒβœ…~βœ…βŒβŒβœ…βœ…βŒβŒ
tip

Picking a CMS is a very personal decision, and there is no one-size-fits-all solution. You should consider your team's experience, the project's requirements and your budget.

Β· 8 min read

We are giving away to our community a free a month of FireCMS Cloud Plus with the code IMONFIRE.​

FireCMS 3.0 The Next CMS that is already here.πŸ”₯​

Three years ago we launched the first version of FireCMS. We started offering an open source core so that anyone could build whatever they need. FireCMS started as an internal tool that we offered to our clients. The usual use case is: you are building an app or a web using Firebase as a backend, and need a backoffice tool to manage your data, your users, your files. Everything in a secure environment and with a strong roles and permissions system. Along the years, we have developed full stack solutions for partners like as Oikosbrain, medicalmotion or ThePlanetApp. Likewise, many agencies have benefited from the open-source nature of the project and use it to develop internal apps for their own clients. Since it’s inception, FireCMS has been downloaded 200k+ times in NPM.

Along the years we understood that we need to make it simple for the customer to install and configure FireCMS, but also keep the power of using code to extend the base product with any feature. We helped customers build extensions for other database providers, such as MongoDB, or create a 3D model editor using Three.js. And that’s our focus for the next years: Build the best no-code CMS, while preserving all the customization options in code, and ease of use our users love.

Launching the Beta version of FireCMS 3​

We have put a lot of effort into building a hosted version of the collection editor, including most of the customization an validation oprions. We provide a great UI, and you extend it however you need.

☁️ The Cloud Version​

One of the most significant additions to FireCMS 3.0 is the introduction of the SaaS cloud-hosted version. This new offering allows users to easily access and manage their FireCMS projects directly from the cloud. With this feature, users no longer need to worry about setting up and maintaining their own infrastructure, as FireCMS takes care of it all. This greatly simplifies the deployment process and allows end users to focus more on building their applications.

You no longer need to manually update CMS versions since every update is pushed to the cloud and received by all clients.

πŸ”‘ The customers still own the data​

Your data is yours, we don’t need to access it. Each FireCMS project is linked to a Firebase project, that is owned by you, the customer. We just provide the interface to manage the data. If you need, we also help you creating and configuring the Google Cloud project and the Firebase project. We can help you with the process. Starting now.

πŸ§‘β€πŸ’» Customization with Code​

With FireCMS 3.0, customization options have been taken to the next level. Now, users can leverage the power of code to personalize their CMS even further. Whether it's tweaking the layout, adding custom fields, or implementing complex business logic, developers have the flexibility to extend and modify FireCMS to suit their specific needs. This level of customization empowers users to create truly unique and tailored CMS experiences. We even built a CLI for that. Start the project, write the code, upload it and find the features in the app. Extend the React basecode with Typescript or Javascript.

An example of highly customized instance of FireCMS, with the ThreeJS editor integrated

An example of highly customized instance of FireCMS, with the ThreeJS editor integrated

We have also built a CLI for making the interaction with the Cloud easier. Start the project, write the code, upload it and find the features in the app. Extend the React base code with Typescript or Javascript.

And just deploy with one command:

firecms deploy

New UI collection schema editor​

Originally, collections were only defined in code. Now, you can do it with a UI as well. Add fields, add collections, property types, files, images. All the properties, now they can be configured with a few clicks. If you need to add some logic to your collections, like enabling some fields based on other values, you can get the code for your current collection

FireCMS collection editor

But it gets even better! FireCMS can automatically detect new values and add them to the schema with just a single click. This empowers users to easily customize and adapt their collection schemas to meet their evolving needs.

Even though the collection schema is now stored in the backend, you still maintain full control over which properties can be modified from the user interface. Moreover, you have the ability to define default values for new documents, ensuring consistency and efficiency in data management.

New data inference​

Do you have a few collections in your project and want to get started quickly? FireCMS can now infer the schema from your data. This means that you can begin using FireCMS in just a few minutes, without the need to write a single line of code. Simply import a data file and start immediately.

πŸ’½ Data import and export​

Now, you can import and export the data. As we've stated, you are the owner of the data and it's up to you to decide.

Import​

You can now import data from CSV, JSON, or Excel files. This feature is excellent for migrating data from other systems. We have incorporated a modern UI that enables you to define how the data is imported and how it is mapped to your collections.

Import data view

Export​

You now have better control over how your data is exported:

  • Define the format of your timestamps.
  • Define how arrays are serialized in CSV files (assigning one column per array item, or serializing the array as a string).
  • Export your data as JSON or CSV.

πŸ€– GPT-4 Content Generation​

We have improved our interface to enable content generation. You can create a complete database row from a prompt, a title, or any available field. We also provide a UI to perform various actions such as summarizing, translating, and expanding. Whatever you can think of is ready to use. We use GPT-4 under the hood.

🚀 Performance improvements​

Versions 1.0 and 2.0 of FireCMS were based on Material UI (mui). This was great for getting started quickly, but it had some drawbacks. The main one was that performance was not great. The styling solution of MUI is based on emotion which resolves styles at runtime. This means that the browser has to do a lot of work to resolve the styles. This is not a problem for small applications, but it can be a problem for large applications.

In FireCMS 3.0, we have migrated to Tailwind CSS. This is a utility-first CSS framework that allows us to generate a small CSS file with all the styles resolved at build time. This means that the browser does not have to do any work to resolve the styles, which results in a much faster experience. πŸš€

πŸ‘₯ Roles and permissions​

Now you can leverage out of the box invitations, user management, and a role system. The default ones, Viewer, Editor, or Admin, or create your own custom ones.

Search out of the box. No need to create an index or to rely on a third-party provider, type and find your records. We look through all the fields and perform a smart search. Just click on search and start typing.

🎨 New components library, theming and better icons​

In FireCMS 3.0, components, icons and colors have received a significant upgrade.

We have built a full component library

The new release includes an expanded set of icons, giving users more options to choose from when designing their CMS. Additionally, the color palette has been expanded, allowing for greater flexibility in creating visually appealing interfaces. These enhancements enable developers to create stunning and intuitive CMS designs that align with their brand and aesthetic preferences.

Pricing​

We decided to provide a free tier of use of the CMS. FireCMS Cloud Free. This is everything you have in the Free version:

  • Unlimited projects
  • Unlimited collections
  • Custom fields and custom views
  • Customization with Code
  • All available form fields
  • Schema editor and inference from data
  • Advanced data import and export
  • Default roles
  • 3 users

If you need some extra features, we have FireCMS Cloud Plus, which includes:

  • Everything in the free tier
  • Local text search
  • Unlimited users and roles
  • Unlimited data export
  • Theme and logo customization
  • Custom user roles
  • GPT-4 content generation

While the free plan is, well, free, the Plus is 9,99€ per customer per month. We are continuously going to add features, provide support, and a live web app where you can find your projects.

How to get started?​

Go to app.firecms.co and create your project.

We are giving away a free month of Plus customers to everyone using the code IMONFIRE at the checkout.

What are you going to build?​

We want to hear about it :) Find us on Discord, LinkedIn, or ping us at hello@firecms.co

Β· 3 min read

Nowadays, search is a basic feature in a public online tool. It’s a commodity, a feature that you expect to be there. Can you imagine using a database manager and not being able to search through your records? What happens when you have 500 rows?

Text Search is not that easy at scale​

Now, if you are familiar with our tech stack, particularly Firebase and Firestore, you would know that it’s not such an easy task. In the past versions of FireCMS, we recommended using Algolia as an external plugin. Or any other compatible solutions, since you are in charge of everything, as in any open source product.

But what happens when you need it in a SaaS formulation. Recently, we launched FireCMS Cloud. We still allow customers to host their own Google Cloud project resources, but the app used for managing the data is on our side. So, we are in charge of the CMS, you don’t need to worry about that. Okay, great. We help you manage the app, rolling updates, support, and everything else.

But, how can you build text search features for every project without indexing each one of your records? Well, there are many responses, from using an external platform, such as Algolia, having our own Elasticsearch cluster or if you want to be fancy, even using a Vector store, where you could have real semantic search.

Lean Solution​

Okay, but that requires some work and we are not 100% sure that’s something all our customers want. In fact, we have very little feature requests regarding this feature. So, we decided to go for a Lean solution. Start with something small, but powerful enough to provide a solution meanwhile we think for a better solution. But still, something that can help us validate that this will be helpful.

So we decided to implement in-browser search. Storing a local cache in the browser. It’s not the best solution in the market, it’s probably a little slow for big collections. But it’s something that works right away. And solves the search for most of our customers.

And what’s the best thing? You can activate it right away in your FireCMS Cloud project. We just rolled it out for everyone.

text_search_dialog.png

Now, our customers from Botanica Madrid can find any exotic named plant, such as a Zamioculca.

botanica_search.png

Go try it and tell us what you think.

Conclusion​

So, when your team is small, sometimes it's helpful to build and release fast. Test, measure, and check if the development effort may satisfy a problem your customers are having.

Anyway, if you need a hand setting up a project, you have any issue, or you need help building a feature, reach us out at hello@firecms.co.2023-09-19-openai_code_migration.md

Β· 6 min read

In the day-to-day world of development, activities such as refactoring and migrating code consume a significant amount of time. Tasks such as restructuring code packages, renaming variables, altering function signatures, among others, are often tedious and fraught with errors. These operations can be effectively automated with the assistance of artificial intelligence. This article explains how to use OpenAI's GPT-4 to automatically refactor and migrate code.

At FireCMS, a prime motivation for adopting this approach is the migration of code from the JavaScript CSS library emotion to the CSS framework tailwindcss. This article specifically covers how to automatically convert code from emotion to tailwindcss, but the approach can be generalized to automate migration among any pair of libraries.

emotion allows components to be styled using JavaScript and tailwindcss offers the use of CSS classes to style components. While emotion carries a runtime footprint, tailwindcss works on a build-time footprint. Consequently, switching from emotion to tailwindcss can substantially improve the performance of an application.

This article demonstrates the creation of a basic Node.js script to automate the above-mentioned process, thereby extending the approach to handle any code migration scenario.

Note that you can apply the same approach to any other code migration.

Identifying the Problem​

  • Emotion defines styles utilizing the sx prop, as shown in the code snippet below, which presents a button with a red background:
import {Button} from "@mui/material";

const MyButton = () => {
return <Button sx={{backgroundColor: "red"}}>Click me</Button>
}
  • Contrarily, tailwindcss uses CSS classes to define styles, as shown in the following code snippet, which defines a similarly-styled button:
import {Button} from "@mui/material";

const MyButton = () => {
return <Button className="bg-red-500">Click me</Button>
}

The goal is to construct a script capable of automating the conversion of code from emotion to tailwindcss style definitions.

Automating Code Migration through AI​

The Node.js script illustrated here traverses the source code's folder structure and replaces emotion styles with tailwindcss styles. This process involves identifying JSX ot TSX elements containing the sx prop and replacing them with their corresponding className prop.

Traversing the Code​

Here's a simple function that recursively traverses the source code's folder structure, returning all file paths and their contents:

const getRecursiveFileReads = async (dir: string, onFileRead: (filePath: string, content: string) => void) => {
const files = await fs.readdir(dir);
for (const file of files) {
const filePath = path.join(dir, file);
const stat = await fs.stat(filePath);
if (stat.isDirectory()) {
getRecursiveFileReads(filePath, onFileRead);
continue;
}
const content = await fs.readFile(filePath, { encoding: "utf8" });
onFileRead(filePath, content);
}
}

Detecting Emotion Styles​

To identify sx props within the file content, we use a regular expression as shown:

const sxRegexp = /(sx=\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\})/g;

This regular expression matches the sx prop as well as its value and can identify the styles defined in sx as shown in the earlier sections.

Replacing Emotion Styles with Tailwindcss Styles​

Now, let's employ a function to replace the sx prop with the className prop. GPT-4 from OpenAI will be utilised to generate the className prop value in response to the following prompt:

You are a tool which only purpose is converting sx props from the emotion library to tailwind classes.
If there is no obvious translation, use classes and styles. E.g:

sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
height: '100vh',
backgroundColor: 'red',
}}

converts to:

className="flex items-center justify-center w-full h-screen bg-red-500"

Return exclusively results in the form of 'className="..."' or 'style={{...}}'
since your output will be injected into a tsx file.

We are instructing GPT-4 to generate the className prop value. We are also instructing GPT-4 to return exclusively results in the form of className="..." or style={{...}} since our output will be injected into a tsx file.

Any other output from GPT-4 would result in invalid code.

We will use the OpenAI library to make the corresponding call:

import { Configuration, CreateChatCompletionRequest, OpenAIApi } from "openai";

export const openai = new OpenAIApi(new Configuration({
apiKey: "YOUR_API_KEY"
}));

async function getOpenAiReplacement(input: string) {
const completionParams: CreateChatCompletionRequest = {
model: "gpt-4",
messages: [
{
role: "system",
content: systemInstructions
},
{
role: "user",
content: input
}
],
temperature: 0.7,
top_p: 1,
};

const completion = await openai.createChatCompletion(completionParams);
return completion.data.choices[0].message?.content;
}

Full script​

Finally, having all the snippets together enables us to write the full script. Replace FOLDER with the path of the source code you want to migrate, and remember to add your OpenAI API key.

You can run this script with ts-node script.js. If you prefer a dry-run mode, just set dryRun to true.

The complete script is attached below:

import path from "path";
import * as fs from "fs/promises";

import { Configuration, CreateChatCompletionRequest, OpenAIApi } from "openai";

const FOLDER = "../src";

export const openai = new OpenAIApi(new Configuration({
apiKey: "YOUR_API_KEY"
}));

const dryRun = false;
const sxRegexp = /(sx=\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\})/g;

const getRecursiveFileReads = async (dir: string, onFileRead: (filePath: string, content: string) => void) => {
const files = await fs.readdir(dir);
for (const file of files) {
const filePath = path.join(dir, file);
const stat = await fs.stat(filePath);
if (stat.isDirectory()) {
getRecursiveFileReads(filePath, onFileRead);
continue;
}
const content = await fs.readFile(filePath, { encoding: "utf8" });
onFileRead(filePath, content);
}
}

let count = 0;

getRecursiveFileReads(FOLDER,
async (filePath, content,) => {
if (content.includes("sx={")) {
let newContent = content;
let match;
while ((match = sxRegexp.exec(content)) !== null) {
const sxData = match[1];
console.log(sxData);
if (!dryRun) {
const replacement = await getOpenAiReplacement(sxData);
if (replacement) {
console.log(replacement);
newContent = newContent.replace(sxData, replacement);
}
}
}
fs.writeFile(filePath, newContent);
count++;
console.log("Processed files", count);
}
});


async function getOpenAiReplacement(input: string) {
const completionParams: CreateChatCompletionRequest = {
model: "gpt-4",
messages: [
{
role: "system",
content: systemInstructions
},
{
role: "user",
content: input
}
],
temperature: 0.7,
top_p: 1,
};

const completion = await openai.createChatCompletion(completionParams);
return completion.data.choices[0].message?.content;
}

const systemInstructions = `You are a tool which only purpose is converting sx props from the emotion library to tailwind classes.
If there is no obvious translation, use classes and styles. E.g:

sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
height: '100vh',
backgroundColor: 'red',
}}

converts to:

className="flex items-center justify-center w-full h-screen bg-red-500"

Return exclusively results in the form of 'className="..."' or 'style={{...}}'
since your output will be injected into a tsx file.`

Conclusion​

This process has been successfully applied to the FireCMS codebase, resulting in a significant reduction in the runtime footprint of the application. It has helped us intensively in a very tedious task. Of course some manual work is still required, but a good part of the work is done.

Of course, you can think of ways of improving this script. For example, you could tell OpenAI your tailwind.config.js content, so it can generate the classes based on your configuration.

I hope you enjoyed this article and that it will help you in your next code migration!

Β· 4 min read

react_code

React has taken the development ecosystem by storm, and it's no surprise that it plays a pivotal role in the future of content management systems (CMS) too. But, why exactly should you choose a React-based headless CMS for your next project? Developers and content creators alike, prepare to be amazed as we delve into the numerous reasons why a headless CMS built on React is the ultimate choice.

A New Era of CMS: Headless Over Traditional​

Before diving into the numerous benefits of using a React-based headless CMS, let's quickly recap the concept of a headless CMS.

Unlike traditional CMSsβ€”which tightly couple the front-end presentation layer with the back-end content management systemβ€”a headless CMS decouples these two layers. This separation of content management and presentation layer allows you to work with a robust API and any front-end technology of your choice to create future-proof, blazing fast, and highly customizable experiences.

Now, let's get into why choosing a React-based headless CMS in particular can revolutionize your projects!

Unleashing React's Powerful Potential​

React, a widely popular JavaScript library created by Facebook, simplifies the process of creating interactive and lightning-fast user interfaces. As such, integrating a React-based headless CMS into your projects unlocks multiple benefits, including:

blog_example

1. Reusable Components​

React operates on the principle of breaking your UI into isolated and reusable components. These components can be quickly repurposed for various projects and use cases, allowing developers to maintain efficiency and consistency in their work. Consequently, this facilitates seamless integration with a headless CMS, allowing you to display content across multiple platforms easily and consistently.

2. Performance & Speed​

React utilizes a virtual DOM (VDOM), which optimizes rendering processes, greatly enhancing your application's performance. Websites that deliver content through a React-based headless CMS showcase an outstanding rendering speed, resulting in enhanced user experience and better SEO rankings.

3. Progressive Web App (PWA) Support​

React boasts excellent support for building PWAs. By integrating your headless CMS with a React-built PWA, you can create web experiences that are reliable, fast, and engaging – even on unstable networks. This combo allows you to reach a larger audience and offer the same user experience as native apps, while maintaining full control over content delivery.

4. Growing Ecosystem​

The React ecosystem is thriving and continually expanding, giving developers access to a plethora of open-source libraries, tools, and components. These resources simplify the construction and maintenance of your user interface and integration with your headless CMS, ultimately speeding up your project's development cycle.

Empowering Content Creation​

A React-based headless CMS not only benefits developers but also empowers content creators with the following:

1. Content-first Approach​

Headless CMS solutions put content at the forefront, allowing creators to focus purely on building engaging and high-quality content without the constraints of a predefined presentation layer. This content-first approach gives you the freedom to edit and manage content across multiple platforms, including web, mobile, and IoT devices, effectively increasing your reach.

2. Flexibility and Customization​

A React-based headless CMS allows content creators to customize their editorial workflows to suit their requirements better. Custom content types, taxonomies, and metadata can all be seamlessly managed and edited, ultimately fostering a more efficient and tailored approach to content creation.

3. API-driven Content Delivery​

API-driven content delivery simplifies the integration process between your headless CMS and the front-end, allowing you to update content in real-time or display content to multiple platforms from a single source. This can lead to streamlined workflows, cost savings, and improved productivity.

Wrapping Up​

In conclusion, using a React-based headless CMS like FireCMS in your projects is nothing short of game-changing. FireCMS brings together the best of both worlds, empowering developers to create dynamic, high-performance applications while enabling content creators to manage and deliver flexible, platform-agnostic content.

Built using the powerful and popular Firebase and React frameworks, FireCMS offers an extensive array of components and customization options to its users. With its modular architecture, features such as reusable components, blazing fast performance, and a thriving ecosystem are accessible right out of the box.

Additionally, FireCMS provides content creators a content-first approach with the flexibility and customization needed for modern workflows. Combined with the power and flexibility of Firebase content delivery, FireCMS enables streamlined workflows, cost savings, and improved productivity for both developers and content creators.

With FireCMS, your investment in a React-based headless CMS will continue to pay dividends for years to come as the ecosystem keeps growing and improving. If you're looking for a future-proof, powerful, and customizable content management solution, then look no further than FireCMS!

Β· 6 min read

pawel-czerwinski-C2tWWNKExfw-unsplash.jpg Content Management Systems (CMS) are widely used across various industries to create, edit, and manage digital content. These platforms have evolved with time, offering more advanced features, functionality, and integration options. One of the most recent and promising developments in this area is the integration of ChatGPT, a powerful AI language model, into existing CMS systems.

Imagine a world where content management is no longer a tedious, time-consuming process. A world where your CMS system can understand context, translate languages, and even generate content on its own. Sounds like a dream come true, right? Well, thanks to ChatGPT, this dream is quickly becoming a reality. In this article, we’ll explore how ChatGPT, the AI-powered language model, can revolutionize content management systems by swooping in like a superhero to save the day β€” and your content!

ChatGPT: A Brief Overview​

ChatGPT, developed by OpenAI, is a cutting-edge AI language model that can generate human-like text based on the input provided. It leverages advanced machine learning algorithms and natural language processing capabilities to understand context, generate responses, and even translate languages. This technology has immense potential for integration into various digital platforms, including CMS systems.

codioful-formerly-gradienta-26WixHTutxc-unsplash.jpg

How ChatGPT Can Enhance CMS Systems​

Picture ChatGPT as the superhero sidekick to your CMS. It’s here to help you tackle content management challenges and make your life easier. Let’s take a look at some of the extraordinary abilities it brings to the table:

1. Autofilling Fields ChatGPT can be used to autofill fields within a CMS, saving time and effort for content creators and editors. By analysing the context of a specific entry, the AI can generate relevant content, titles, descriptions, tags, or other metadata required by the system.

2. Completing Missing Data In some cases, CMS users might have incomplete data sets or face difficulty in finding the right information to fill specific fields. ChatGPT can analyze the available data and generate the missing information, ensuring a more comprehensive and accurate content record.

3. Translations With its advanced language processing capabilities, ChatGPT can provide translations for content within a CMS, allowing content creators to easily publish their work in multiple languages. This feature can help businesses reach a wider audience and improve global engagement.

4. Content Generation ChatGPT’s ability to generate human-like text can be used to create new content within a CMS. For example, it can generate blog posts, product descriptions, or other content types based on the user’s input, substantially reducing the time and effort required.

5. Content Optimisation ChatGPT can analyse existing content and suggest improvements to enhance readability, SEO, and user engagement. It can help identify and fix grammar, spelling, and punctuation issues, as well as optimize keyword usage, headings, and metadata to improve search engine rankings.

6. Content Personalisation By leveraging user data and analytics, ChatGPT can generate personalized content recommendations for individual users. This could include tailoring article suggestions, product recommendations, or other content based on user preferences, browsing history, and demographics, leading to a more engaging user experience.

7. Content Summarization ChatGPT can automatically generate concise summaries of articles, reports, or other long-form content within the CMS. This feature can help users quickly understand the main points of a piece of content without having to read the entire text, making it easier to browse and navigate the website.

8. Automated Content Curation ChatGPT can be used to automatically curate content for newsletters, roundups, or other compilation-style posts. By analyzing user preferences, topic relevance, and content popularity, ChatGPT can generate a list of suitable articles or pieces of content to be included in such compilations, saving time and effort for content creators and editors.

9. Comment Moderation Integrating ChatGPT with a CMS can help facilitate automated comment moderation. The AI can analyze user-generated comments for spam, inappropriate language, or other violations of community guidelines, and either flag or remove them automatically, ensuring a safe and welcoming environment for users.

10. FAQ Generation ChatGPT can assist in creating Frequently Asked Questions (FAQs) sections for websites by analyzing existing content and user queries. This feature can help businesses quickly address common concerns and questions from their audience and improve overall user experience.

11. Topic Research ChatGPT can be used to generate content ideas and topics for articles, blog posts, or other forms of content. By analyzing trends, user interests, and related content, the AI can suggest fresh and engaging topics for content creators to explore.

These are just a few examples of the many potential use cases for integrating ChatGPT with a CMS. As AI technology continues to evolve, the possibilities for enhancing content management and user experiences will only grow.

CMSs

FireCMS: Extracting Structured Data from ChatGPT Outputs​

As impressive as ChatGPT’s capabilities are, it’s essential to ensure that its outputs can be effectively integrated into a CMS platform. FireCMS, an open-source CMS, demonstrates a successful approach to extracting structured data from ChatGPT outputs and adapting it to any given data entity structures.

FireCMS can be configured to communicate with ChatGPT, sending input queries and receiving generated content. By implementing custom parsers and data processing tools, FireCMS can extract the relevant information from ChatGPT’s outputs and adapt it to the required data structure. This process allows FireCMS to seamlessly integrate ChatGPT-generated content into its existing content management workflow.

The integration of FireCMS with OpenAI is completely free to try in your own project, no subscriptions required!

https://youtube.com/shorts/WIfHyvDRam0

Conclusion​

The integration of ChatGPT into CMS systems has the potential to revolutionise content management, making it more efficient, accurate, and versatile. By autofilling fields, completing missing data, providing translations, and generating content, ChatGPT can streamline content creation and management processes while offering a higher degree of automation.

FireCMS showcases a successful approach to integrating ChatGPT into a CMS platform, setting the stage for other CMS systems to follow suit. As AI technology continues to advance, the potential for further improvements and innovations in content management is limitless.

Β· 4 min read

Dark mode

FireCMS 1.0 is ready to ship! πŸ™Œ abd why Firebase makes for an amazing developer experince

A few months have passed since we entered the beta period of FireCMS, our Firestore-based CMS built with developer experience in mind.

We have collected your feedback to add new features and quality of life improvements, fixed bugs, and merged your PRs (thank you!).

After reaching more than 500 stars on GitHub, and 100 forks, it is a good time to finally end the beta and release-candidate phases and ship version 1.0.0

Why Firebase and FireCMS​

At Camberi, we have been developing web apps and mobile apps for a long time. We have used Firebase and Firestore as a backend and database in multiple projects.

Our experience overall has been great!

Firebase offers a very powerful backend out of the box, and allows to kickstart a project in no time. It provides SDKs for the most relevant platforms, such as web, iOS or Android (and more) and has some features that make it stand out, like real-time data synchronisation and its scalability.

If you need to start a new project and don't want to spend too many resources in the backend, Firebase is the way to go. But this doesn't mean you can't build complex apps with it!

If you are coming from a more traditional backend setup you will need to make a bit of a mind switch. You can extend the functionality of your backend using functions, and have triggers when the data in your database gets updated.

Also, you are not forced to connect your apps to Firestore and you can build have a REST API or use callable functions to have your backend logic.

And, even if you don't want to use any of the Firebase services, because you already have your auth and APIs in place, you can set up a Firebase with FireCMS project just to manage your content.

We built FireCMS out of necessity.

If you are coming from a SQL background you will need to get used to de-normalising your data and having limited querying capabilities

Where we are​

For every Firebase project that we developed for a client we needed a way to manage their content, and provide a backend admin panel. So we built our own!

After more than 2 years of development, FireCMS has gone from a simple app that would let us produce some simple CRUD views over collections to a full-blown CMS that includes:

  • Detailed CRUD views for collections.
  • Super powerful data tables with inline editing, alla AirTable.
  • Awesome, performant and beautiful UI.
  • Form views with more than 20 different widgets, including advanced ones such as:
    • File uploads
    • Reference support for different collections
    • Date time
    • Enumerations
    • ...and many more!
  • Possibility to customise your own form fields and how the underlying data is rendered.
  • Possibility to build fields based on other values.
  • Subcollections support.
  • Virtualized views for performance.
  • Text search support.
  • Customisation the CMS based on the logged-in user.

FireCMS offer more customization options than any other alternative, such as Rowy or Flamelink. It even offers features that are not available in some well established CMS like WordPress or Strapi, like the inline editing.

The future​

We keep on getting amazed on how you are finding innovative ways to use FireCMS and we want to make it easier for you to do so.

We are already working on version 2 of FireCMS and are improving on almost every aspect of it:

  • Forms layouts and performance.
  • Internal and external APIS
  • Reusability of internal components
  • Property builders at any level of your property tree, not just at the root.
  • Improved modularity and reusability of components

Β· 5 min read

Exciting times for our project!

After more than 60 releases, and numerous refinements of the internal components and APIs, we are ready to start the beta release of version 1.0.0 πŸ’ƒ

We now consider that the code and the UX and UI are mature enough to create a beta release (though we have multiple instances of previous versions already in production!).

In the last months we've been focused on improving the CMS quality by doing a lot of internal restructuring that is also going to affect the public facing APIs.

A bit of background​

We started building FireCMS out of necessity. We were working on several projects based on Firebase and in most of them we needed to develop some kind of backend admin panel/CMS. We took some of those tools we had built, and merged them into a single generic project that would support any database structure and data type. We needed to make sure that we would need to be able to customize many aspects of each implementation based on the necessity.

The outcome was a very good starting point to what would become FireCMS after many iterations and feature updates. One of the consequences of this approach was that the code was tightly coupled to Firebase, and you could find imports to Firebase code in most layers of the code.

The influence of Firebase​

The original coupling to Firebase and specially the data structure of Firestore has influenced many aspects of this project. The way we create entities based on documents and collections and subcollections mimics the Firestore data structure. What seemed like a limitation has turned out to be an opportunity to think of a great UI.

At FireCMS we have a special passion for user experience and believe that internal admin tools don't always receive the love they deserve.

In this time, we have developed some high quality components such as the spreadsheet views of collections, or the side panel to edit entities and nested subcollections.

Where we are going​

In the last year, we have seen developers integrate FireCMS in ways we had never imagined! We have tweaked the APIs to try to accommodate those requirements, but we have come to the conclusion that a bigger change was needed.

The result is a big rework of the internal APIs and components that improves re-usability and customisation.

We have also added a lot of minor performance tweaks as well as design tweaks and improvements, including a very awesome new dark mode!

If you are using FirebaseCMSApp (previously CMSApp), so FireCMS as a standalone app, you will need to update some APIs (see the Migrating from alpha versions).

But, but, but... If you need more customisation you can now completely override FirebaseCMSApp and reuse all its internal components. This means you now have control of the MUI theme (adapted to V5), the CMS routes (adapted to React Router 6), or how you display the different parts, such as the side dialogs, or add your own.

You are now free to integrate the new FireCMS component and reuse all the internal components, combine them with your own, build your own custom themes or custom backend implementations.

Separation of concerns​

In the process of having a cleaner code, all the code related to Firebase has been isolated into 3 components, one for authentication, one for the data source and one for storage. These components are abstracted away behind their respective interfaces. This means you can replace any of those parts with your custom implementation!

We have three new types that abstract away the services provided by Firebase:

  • AuthDelegate, in charge of handling the auth operation such as login or sign out, and build the logged-in user.
  • DataSource, in charge of handling data operation (fetch, listen, save, delete).
  • StorageSource, in charge of dealing with file storage operations.

We provide implementation for using Firebase Auth, Firestore and Firebase Storage, assigned by default if you use FirebaseCMSApp.

This means that you are now able to use FireCMS with any backend, auth or storage solution. If you want to go this way, you can check an example implementation of FireCMS that uses the internal components instead of FirebaseCMSApp

How did it go?

If you have been using FireCMS with a custom backend, we would love to hear your feedback either in our Discord channel or directly at hello@firecms.co 😊

Code quality​

We have done a huge internal refactor that affects pretty much every part of the CMS. We have now a much better separation of the internal packages. There is also a package named firebase_app which encapsulates an implementation of FireCMS that uses the Firebase services as backend.

All the code referring to Firebase can be found only in this internal package, and nowhere else. This means the core of FireCMS has been completely isolated from Firebase and is now much more maintainable and extendable.

We have got a lot of PRs and support from out users and would love to foster that participation going forward. A cleaner code will help everyone involved and allow for more and better features!

Β· 4 min read

Types update​

We have a big update in version 0.49.0 affecting the main types used in the CMS.

The signature of EntitySchema<Key extends string = string> has changed to EntitySchema<M> where M is your model type like:

import { buildSchema } from "@camberi/firecms";

type Product = {
name: string;
price:number;
}

const productSchema = buildSchema<Product>({
// ...
properties:{
name: {
dataType: "string",
// ...
},
// ...
}
// ...
});

This change propagates to all the rest of the types used internally and in the public API, especially to all the types that had EntitySchema as a generic type argument.

For example EntityValues (representing the data related to an entity) had the signature EntityValues<S extends EntitySchema<Key>, Key extends string> and now it is simply EntityValues<M>. You may use EntityValues or any other type that includes a schema as a type if you have callbacks in place or have implemented custom views.

This affects in an equal way all the types that are exported. In order to migrate to the new version you need to make sure that you don't have any references like EntityCollection<typeof productSchema>, like the ones we had in the previous examples. In that case you can create your Product type if you want better type checking or simply remove it.

Motivation​

Let's face it, the type system related to schemas until now was a mess.

It had become overcomplicated and was not providing enough type information in the callbacks. Not it is much straightforward.

Robustness​

I have always found it annoying all the Javascript frameworks that use the module.exports system for configuration. I find myself going always back and fort from the IDE to their website to get the information I need, even if I have an idea.

Configuration as code with a strong type system is a whole other level.

The new system is now able to tell you exactly what you are configuring wrong, or suggest the props you are looking for. The following is a configuration error because we are assigning the multiline config, which applies only to strings, to a number property:

// ...
name: {
dataType: "number",
title: "Name",
config: {
multiline: true
},
validation: { required: true }
}
// ...

So it indicates a type error:

Configuration error

Migration examples​

For example, if you had a callback including EntityValues, you would know the property keys you had defined, but not the types.

import { buildSchema } from "@camberi/firecms";

type Product = {
name: string;
price: number;
}

export const productSchema = buildSchema<Product>({
name: "Product",
onPreSave: ({
schema,
path,
id,
values,
status
}) => {
// Now values is of type `Product`
console.log(values);
return values;
},

properties: {
name: {
dataType: "string",
title: "Name"
},
price: {
dataType: "number",
title: "Price"
}
}
});

With this update you get a complete type system in all your callbacks, which will help prevent errors.

Use without specifying the type​

There is a way to get the same type validation without indicating the type explicitly. You can wrap each property with buildProperty to get the same result

import { buildSchema, buildProperty } from "@camberi/firecms";

export const productSchema = buildSchema({
name: "Product",
onPreSave: ({
schema,
path,
id,
values,
status
}) => {
// Now values is of type `{ name: string; price: number; }`, so
// equivalent to the previous example
console.log(values);
return values;
},

properties: {
name: buildProperty({
dataType: "string",
title: "Name"
}),
price: buildProperty({
dataType: "number",
title: "Price"
})
}
});

This way of building your schemas is not encouraged, but it may be useful for simplifying your migration.

In case you need to retrieve the type of the schema you have created, we now include a utility type called InferSchemaType that could be useful if you had code like buildCollection<typeof productSchema>, which now would simply turn into buildCollection<InferSchemaType<typeof productSchema>>

We know that it can be a bit frustrating to migrate code to a newer version and fix breaking changes, but we are convinced that this is a change for the better, making our life and our users easier πŸ˜‰

Affected types and methods​

All the following types and methods have seen their types changed from <S extends EntitySchema<Key>, Key extends string> to <M>

  • EntityCollection
  • AdditionalColumnDelegate
  • PermissionsBuilder
  • ExtraActionsParams
  • FilterValues
  • EntityCustomView
  • EntityCustomViewParams
  • EntitySaveProps
  • EntityDeleteProps
  • Entity
  • EntityValues
  • FieldProps
  • FormContext
  • CMSFormFieldProps
  • Properties
  • PropertyBuilderProps
  • PropertyBuilder
  • PropertyOrBuilder
  • listenCollection
  • fetchCollection
  • fetchEntity
  • listenEntity
  • listenEntityFromRef
  • createEntityFromSchema
  • saveEntity

And some other components that are only used in advaced use cases.

Β· 4 min read

Welcome to the FireCMS blog!​

We will use this blog to keep you up to date of the latest updates regarding FireCMS, as well as case-studies!

But first, a quick introduction on how we ended up building our own generic headless admin panel/CMS solution based on Firebase!

We started Camberi as an apps and web development agency in 2018. We all were experienced Firebase users, and we found it was a great fit to start new projects, requested by clients.

Motivation​

Usually clients would like to develop an app or a webapp, and most times they would need an additional tool for backend administration. We built 3 tools for different projects, that were similar but slightly different. They were all React projects. We soon realized a generic solution would help us a lot, so we thought: There must be a generic headless CMS based on Firebase/Firestore right?

Right! There were some solutions out there, but we found problems with all of them, which stopped us from using them:

  • Either they were generic CMS tools that were not optimised for the Firestore data structure, with its pros and cons (such as React Admin, despite being a great tool).
  • Or they impose a specific Firestore data structure, which means that are not suitable for every project. This is the case for Flamelink, which is a commercial solution based on Firebase, which follows a philosophy more similar to Wordpress.
  • Or they don't provide enough features. The best solution we have found is Firetable, which shares some core concepts of FireCMS, but we find a bit limited in some Firestore specific areas. It is opinionated on a few things, like the way users are stored for example, and we don't like that. They provide a lot of good widgets but not the possibility to use your own easily.

With all the previous factors taken into account, and a pandemic keeping us home, we decided to unify all the tools we had built into a generic one!

Companies put a lot of effort into building their client facing apps but internal admin tools tend to be the ugly ducklings, with huge productivity implications.

Core concepts​

Pretty soon we knew what we wanted to build. Firestore is a no-SQL database with a data structure that consists of collections, that contain documents, that can contain subcollections, and so on. We need that our UI reflects that structure, with an arbitrary level of nested collections.

It is also crucial that that beautiful UI is customizable, and we have added multiple customisation points based on both our needs and your input.

Our headless CMS must allow developers to extend it in any way they need, while keeping it extremely simple to kickstart a new project, with the bare minimum configuration. We need sensible defaults that can be overridden or extended.

Features​

FireCMS allows setting up a CMS in no time, just by introducing your collections and document schemas as input, and it renders beautiful editable spreadsheet-like tables and forms. It also builds all the navigation and authorization views automatically, so you don't have to. All the common use cases are covered out of the box, including strings, numbers, booleans, arrays, maps, references to other documents, timestamps... We also provide more advanced use cases, like:

  • String enumerations with customization.
  • Handling of files such as images, videos or anything really in Google Cloud Storage.
  • We automatically generate complex fields for references to other collections, just by providing the collection path. Also, we handle correctly arrays of references.
  • Markdown fields, with preview
  • Complex typed array structures: such as an array that contains objects of type text, or images, or products like in our blog example!

Again, besides the basic and advanced use cases that are bundled with the library, the CMS allows the developer to customise and override most aspects of it!

Take a look at the docs if you would like to know all the possible options!

We hope you enjoy using FireCMS as much as we do while developing it, and I would like to take the change to thank all the external contributors with feedback and PRs.

You rock! πŸ™Œ

Sign up to our newsletter to get the latest news and updates. No spam!