Hooking-up a headless CMS to React apps


This article shows how to hook up the React version of classical TodoMVC app to a Content Management System and use it to store data. After completing this tutorial, you will have a basic Todo application using React, which will sync its data into a cloud-based Content Management System.


When we’re building web applications, we always hit the problem of storing data somewhere - should it be a database or a file on a cloud storage or something else? Frontend developers, in particular, don’t usually like to play around with setting up servers or AWS services to support their apps. Using a headless CMS is a perfect option in that case. In this short tutorial we will go through setting up Flotiq headless CMS to make it super easy to connect our React application and use it as a permanent data store.


  1. Basic JavaScript knowledge
  2. Interest in React :)
  3. Headless CMS account, we will use Flotiq headless CMS for React (a free account will be just fine)


TodoMVC is one of the most popular projects on GitHub and has been used by thousands of developers as an introduction to different frontend frameworks.

Let’s start with getting this up and running, and it’s straightforward.

  1. Clone the repo

    git clone --depth=1

  2. Navigate to the React example

    cd todomvc/examples/react

  3. Install the dependencies


  4. Start the project!

    yarn run dev

Your browser should now open and display the TodoMVC app, and you can start adding tasks:


Let’s now have a look at the files of this project. It’s really simple, and you can start by looking at the app.jsx file, which will help you understand what’s going on in the application:

The app uses the useReducer hook to manage the state. It’s a simple yet elegant way of dealing with an application state through events. It forces us to structure our code in a cleaner way without directly accessing the state with each user interaction. All state-handling logic is centralised and stored in a component called the reducer.

If you check the reducer.js file, you will see that it follows the best practices for writing reducers :

  • it’s restricted to a bare minimum
  • it doesn’t call any external entities
  • it replaces the state instead of mutating it
  • it uses a switch over the action.type field

We will keep that in mind when connecting to the CMS.

Data model & a headless CMS

Items are the only model in the TodoMVC app, and their model is quite simple:

  • id - a unique identifier of the item,
  • title - a text field containing the title,
  • completed - a boolean flag stating if the item is completed or not.

Before we connect the React application with our backend - we need to set up the data model in Flotiq. Let’s do it now.

  1. Login to Flotiq, you can register a free Flotiq account
  2. Once logged in - create a new Content Type Definition, follow this link or click on

  3. Definition builder in the left sidebar menu

  4. Add definition type in the top right corner
  5. Design the model:

  6. Set the Label to Item

  7. Make sure the API Name is set to item
  8. Add a new text property title
  9. Add a checkbox called completed
  10. Click on the Save button in the top right corner to add the Content Type to the system.

The end result should look like this:

Good job! At this point, your Flotiq account is ready to accept data from the application!


Please note, that we did not explicitly create an id field in the system. Flotiq creates that for us automatically. When we create new objects we will have 2 options:

  • submit them with an ID that we define, or
  • let Flotiq fill-in the id field with autogenerate values.

Connecting React with Flotiq

Now, let’s finally make our todo items persistent! We will implement the following connections between the React TodoMVC app and Flotiq:

  • creating new items in TodoMVC should create objects in the CMS
  • toggling the item’s completion state should also be reflected in the CMS.

Disclaimer - there are many other ways to achieve the same result! Please let us know in the comments if you can come up with other interesting ideas!

Adding new items

The simplest way to achieve that, without breaking the reducer, is to add an API call to Flotiq before a state update event is dispatched. Let’s make these simple changes in app.jsx:

  1. Install node-fetch
    npm install --save node-fetch@2
  2. Add the useCallback import in the first line of app.jsx:
    import { useReducer, useCallback } from "react";
  3. Import node-fetch
    import fetch from "node-fetch";
  4. Add the FLOTIQ_API_KEY const right after the imports (Check this documentation on how to obtain a Flotiq API key).
  5. Finally, add the preDispatch function in app.jsx

    // Find this in app.jsx:
    export function App() {
    const [todos, dispatch] = useReducer(todoReducer, []);
    // Add this:
    const preDispatch = useCallback( async (action) => {
            if(action.type == 'ADD_ITEM'){
                const options = {
                    method: 'POST',
                    headers: {'content-type': 'application/json', 'X-AUTH-TOKEN': FLOTIQ_API_KEY},
                    body: JSON.stringify({title: action.payload.title, completed: false}),
                // Create the object in Flotiq
                const res = await fetch('', options);
                // Retrieve the response to get the object ID
                const data = await res.json();
                // Add the ID as part of payload for the reducer            
        }, []);


    Did you know that Flotiq automatically publishes a set of OpenAPI-compliant endpoints for the content model you define? On top of that there is more - Postman collection, SDKs and API docs, where you can find code snippets that you can simply copy from Flotiq directly into your project!

    Click on the API Docs Link in your Flotiq dashboard:

    Find the endpoint that you need and copy the code. That’s what I did to build this tutorial :-)

  6. Pass preDispatch instead of dispatch to the Header and Main components:

       return (
                <Header dispatch={preDispatch} />
                <Main todos={todos} dispatch={preDispatch} />
                <Footer todos={todos} dispatch={dispatch} />

  7. Last thing - we need to update the existing reducer to support IDs that are generated outside of the reducer itself:

        switch (action.type) {
            case ADD_ITEM:
                return state.concat({ id: === undefined ? nanoid() :, title: action.payload.title, completed: false });

With this, you should now see new items appear in Flotiq while you add them in your TodoMVC!

Toggling item state

We will need to add a couple more changes to synchronise the completion state. The preDispatch function will have to handle another type of action: TOGGLE_ITEM, and we will also have to fetch the current state of the toggle so we can send it to Flotiq. Here’s the complete updated preDispatch:

    const preDispatch = useCallback( async (action) => {

        if(action.type == 'ADD_ITEM'){

            const options = {
                method: 'POST',
                headers: {'content-type': 'application/json', 'X-AUTH-TOKEN': RW_AUTH_TOKEN},
                body: JSON.stringify({title: action.payload.title, completed: false}),

            const res = await fetch('', options);
            const data = await res.json();

        } else if (action.type == 'TOGGLE_ITEM'){

            // Find the toggled item, so we know its state
            const item = todos.find( (item)=>{
                return ==

            const options = {
                method: 'PATCH',
                headers: {'content-type': 'application/json', 'X-AUTH-TOKEN': RW_AUTH_TOKEN},
                body: JSON.stringify({id:, completed: !item.completed}), // negate current value of completed

            const res = await fetch('' +, options);
            const data = await res.json();



    }, [todos]);

That’s it! You will now see the state of the completed checkbox change in the CMS every time you make an update in your app:


In this short walkthrough, we demonstrated how to run the React version of the classic TodoMVC project. We then integrated it with a cloud-hosted CMS, where the data is persisted and can be accessed whenever we want.

Next steps? Fetch the list of todo items from Flotiq when the application starts!

Follow us to get notified about our next article, where we will complete the demo.