diff --git a/docs/Deep-Dives/images/todomvc-react-headless-cms/25bb2df5-3a98-47c0-9c71-39f045209927.png b/docs/Deep-Dives/images/todomvc-react-headless-cms/25bb2df5-3a98-47c0-9c71-39f045209927.png new file mode 100644 index 00000000..18c9508a Binary files /dev/null and b/docs/Deep-Dives/images/todomvc-react-headless-cms/25bb2df5-3a98-47c0-9c71-39f045209927.png differ diff --git a/docs/Deep-Dives/images/todomvc-react-headless-cms/3a687849-d11c-4772-a696-50d7306b3dbe.png b/docs/Deep-Dives/images/todomvc-react-headless-cms/3a687849-d11c-4772-a696-50d7306b3dbe.png new file mode 100644 index 00000000..eeb732c4 Binary files /dev/null and b/docs/Deep-Dives/images/todomvc-react-headless-cms/3a687849-d11c-4772-a696-50d7306b3dbe.png differ diff --git a/docs/Deep-Dives/images/todomvc-react-headless-cms/47208a1b-008c-454d-a89e-1594f3fa108a.png b/docs/Deep-Dives/images/todomvc-react-headless-cms/47208a1b-008c-454d-a89e-1594f3fa108a.png new file mode 100644 index 00000000..ae429712 Binary files /dev/null and b/docs/Deep-Dives/images/todomvc-react-headless-cms/47208a1b-008c-454d-a89e-1594f3fa108a.png differ diff --git a/docs/Deep-Dives/images/todomvc-react-headless-cms/571c3fbe-c165-4f49-acfa-bc29d4a8b268.png b/docs/Deep-Dives/images/todomvc-react-headless-cms/571c3fbe-c165-4f49-acfa-bc29d4a8b268.png new file mode 100644 index 00000000..fbfe09e7 Binary files /dev/null and b/docs/Deep-Dives/images/todomvc-react-headless-cms/571c3fbe-c165-4f49-acfa-bc29d4a8b268.png differ diff --git a/docs/Deep-Dives/images/todomvc-react-headless-cms/76d9cf1e-32cc-49b9-9075-7deac43dd266.png b/docs/Deep-Dives/images/todomvc-react-headless-cms/76d9cf1e-32cc-49b9-9075-7deac43dd266.png new file mode 100644 index 00000000..a349e179 Binary files /dev/null and b/docs/Deep-Dives/images/todomvc-react-headless-cms/76d9cf1e-32cc-49b9-9075-7deac43dd266.png differ diff --git a/docs/Deep-Dives/images/todomvc-react-headless-cms/9dc89923-5852-45a8-a2b3-dea7f2a09979.png b/docs/Deep-Dives/images/todomvc-react-headless-cms/9dc89923-5852-45a8-a2b3-dea7f2a09979.png new file mode 100644 index 00000000..00daaa30 Binary files /dev/null and b/docs/Deep-Dives/images/todomvc-react-headless-cms/9dc89923-5852-45a8-a2b3-dea7f2a09979.png differ diff --git a/docs/Deep-Dives/images/todomvc-react-headless-cms/a14b634d-7d44-4ee2-8e81-04030a8e728d.png b/docs/Deep-Dives/images/todomvc-react-headless-cms/a14b634d-7d44-4ee2-8e81-04030a8e728d.png new file mode 100644 index 00000000..5b7ec7fc Binary files /dev/null and b/docs/Deep-Dives/images/todomvc-react-headless-cms/a14b634d-7d44-4ee2-8e81-04030a8e728d.png differ diff --git a/docs/Deep-Dives/images/todomvc-react-headless-cms/ab9a459f-89f4-4302-9b35-1517096d50a0.png b/docs/Deep-Dives/images/todomvc-react-headless-cms/ab9a459f-89f4-4302-9b35-1517096d50a0.png new file mode 100644 index 00000000..dbd86608 Binary files /dev/null and b/docs/Deep-Dives/images/todomvc-react-headless-cms/ab9a459f-89f4-4302-9b35-1517096d50a0.png differ diff --git a/docs/Deep-Dives/images/todomvc-react-headless-cms/ad7ca7a5-eeaf-4784-8ec1-3ab038cb0ede.png b/docs/Deep-Dives/images/todomvc-react-headless-cms/ad7ca7a5-eeaf-4784-8ec1-3ab038cb0ede.png new file mode 100644 index 00000000..38794d3e Binary files /dev/null and b/docs/Deep-Dives/images/todomvc-react-headless-cms/ad7ca7a5-eeaf-4784-8ec1-3ab038cb0ede.png differ diff --git a/docs/Deep-Dives/images/todomvc-react-headless-cms/b86277ad-72aa-43d0-9df0-236dc00286f0.png b/docs/Deep-Dives/images/todomvc-react-headless-cms/b86277ad-72aa-43d0-9df0-236dc00286f0.png new file mode 100644 index 00000000..eef61842 Binary files /dev/null and b/docs/Deep-Dives/images/todomvc-react-headless-cms/b86277ad-72aa-43d0-9df0-236dc00286f0.png differ diff --git a/docs/Deep-Dives/images/todomvc-react-headless-cms/c39442a7-138b-4c71-b63c-925f8224a63f.png b/docs/Deep-Dives/images/todomvc-react-headless-cms/c39442a7-138b-4c71-b63c-925f8224a63f.png new file mode 100644 index 00000000..eeb732c4 Binary files /dev/null and b/docs/Deep-Dives/images/todomvc-react-headless-cms/c39442a7-138b-4c71-b63c-925f8224a63f.png differ diff --git a/docs/Deep-Dives/images/todomvc-react-headless-cms/d5870a70-fcc9-4ddd-a9c5-1208a7a22faf.png b/docs/Deep-Dives/images/todomvc-react-headless-cms/d5870a70-fcc9-4ddd-a9c5-1208a7a22faf.png new file mode 100644 index 00000000..75beda3c Binary files /dev/null and b/docs/Deep-Dives/images/todomvc-react-headless-cms/d5870a70-fcc9-4ddd-a9c5-1208a7a22faf.png differ diff --git a/docs/Deep-Dives/images/todomvc-react-headless-cms/e18902f8-d6c2-460d-809d-9726811b4af4.png b/docs/Deep-Dives/images/todomvc-react-headless-cms/e18902f8-d6c2-460d-809d-9726811b4af4.png new file mode 100644 index 00000000..70ebaa59 Binary files /dev/null and b/docs/Deep-Dives/images/todomvc-react-headless-cms/e18902f8-d6c2-460d-809d-9726811b4af4.png differ diff --git a/docs/Deep-Dives/images/todomvc-react-headless-cms/f9373293-8b64-4e0b-8ccd-1c72fdd40810.png b/docs/Deep-Dives/images/todomvc-react-headless-cms/f9373293-8b64-4e0b-8ccd-1c72fdd40810.png new file mode 100644 index 00000000..104ba8f4 Binary files /dev/null and b/docs/Deep-Dives/images/todomvc-react-headless-cms/f9373293-8b64-4e0b-8ccd-1c72fdd40810.png differ diff --git a/docs/Deep-Dives/todomvc-react-headless-cms.md b/docs/Deep-Dives/todomvc-react-headless-cms.md new file mode 100644 index 00000000..aab87812 --- /dev/null +++ b/docs/Deep-Dives/todomvc-react-headless-cms.md @@ -0,0 +1,294 @@ +title: Hooking-up React TodoMVC with Flotiq headless CMS | Flotiq docs +description: Discover how to seamlessly connect a headless CMS to your React applications with our step-by-step guide. Learn to use Flotiq with the classic TodoMVC app for efficient data storage and management, making your frontend development smoother and more scalable. +keywords: React, headless CMS, TodoMVC, Flotiq, frontend development, web application, data storage, API integration, JavaScript, React hooks, content management system + + +# Hooking-up a headless CMS to React apps + + +!!! info + 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. + + + +## Intro + +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](https://flotiq.com) to make it super easy to connect our React application and use it as a permanent data store. + +## Prerequisites + + +1. Basic JavaScript knowledge +2. Interest in React :) +3. Headless CMS account, we will use [Flotiq headless CMS for React](https://flotiq.com) (a free account will be just fine) + +## TodoMVC + +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. + + ![](images/todomvc-react-headless-cms/ad7ca7a5-eeaf-4784-8ec1-3ab038cb0ede.png " =627x136"){: .center .width75 .border} + +Let’s start with getting this up and running, and it’s straightforward. + + +1. Clone the repo + ```bash + git clone --depth=1 https://github.com/tastejs/todomvc.git + ``` + { data-search-exclude } + +2. Navigate to the React example + ```bash + cd todomvc/examples/react + ``` + { data-search-exclude } + +3. Install the dependencies + ```bash + yarn + ``` + { data-search-exclude } + +4. Start the project! + ```bash + yarn run dev + ``` + { data-search-exclude } + + +Your browser should now open and display the TodoMVC app, and you can start adding tasks: + + ![](images/todomvc-react-headless-cms/76d9cf1e-32cc-49b9-9075-7deac43dd266.png " =538x445"){: .center .width75 .border} + + +## Code + +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: + + ![](images/todomvc-react-headless-cms/571c3fbe-c165-4f49-acfa-bc29d4a8b268.png " =448x347"){: .center .width75 .border} + +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](https://react.dev/reference/react/useReducer#writing-the-reducer-function) : + +* 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 + + ![](images/todomvc-react-headless-cms/ab9a459f-89f4-4302-9b35-1517096d50a0.png){: .center .width75 .border} + + +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](https://beta.flotiq.com/register) +2. Once logged in - create a new Content Type Definition, follow [this link](https://beta.flotiq.com/content-type-definitions/add) or click on + + + 1. **Definition builder** in the left sidebar menu + 2. **Add definition type** in the top right corner +3. Design the model: + + + 1. Set the Label to `Item` + 2. Make sure the API Name is set to `item` + 3. Add a new text property `title` + ![](images/todomvc-react-headless-cms/a14b634d-7d44-4ee2-8e81-04030a8e728d.png " =627x475"){: .center .width75 .border} + 4. Add a checkbox called `completed` + ![](images/todomvc-react-headless-cms/9dc89923-5852-45a8-a2b3-dea7f2a09979.png " =627x415"){: .center .width75 .border} + 5. Click on the `Save` button in the top right corner to add the Content Type to the system. + + ![](images/todomvc-react-headless-cms/f9373293-8b64-4e0b-8ccd-1c72fdd40810.png){: .center .width75 .border} + +The end result should look like this: + + ![](images/todomvc-react-headless-cms/e18902f8-d6c2-460d-809d-9726811b4af4.png " =538x219"){: .center .width75 .border} + +Good job! At this point, your Flotiq account is ready to accept data from the application! + + +!!! tip + 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` + ```bash + npm install --save node-fetch@2 + ``` + { data-search-exclude } +2. Add the `useCallback` import in the first line of `app.jsx`: + ```bash + import { useReducer, useCallback } from "react"; + ``` + { data-search-exclude } +3. Import `node-fetch` + ```bash + import fetch from "node-fetch"; + ``` + { data-search-exclude } +4. Add the `FLOTIQ_API_KEY` const right after the imports (Check this documentation on [how to obtain a Flotiq API key](https://flotiq.com/docs/API/?h=api+key#application-api-keys)). + ```bash + const FLOTIQ_API_KEY = 'PUT YOUR READ-WRITE KEY HERE'; + ``` + { data-search-exclude } +5. Finally, add the `preDispatch` function in `app.jsx` + ```bash + // 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('https://api.flotiq.com/api/v1/content/item', options); + // Retrieve the response to get the object ID + const data = await res.json(); + // Add the ID as part of payload for the reducer + action.payload.id = data.id; + + } + + dispatch(action); + + }, []); + ``` + { data-search-exclude } + + !!! success + 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: + ![](images/todomvc-react-headless-cms/47208a1b-008c-454d-a89e-1594f3fa108a.png){: .center .width75 .border} + + Find the endpoint that you need and copy the code. That’s what I did to build this tutorial :-) + + ![](images/todomvc-react-headless-cms/d5870a70-fcc9-4ddd-a9c5-1208a7a22faf.png " =323x465"){: .center .width50 .border} + + + + +3. Pass `preDispatch` instead of `dispatch` to the `Header` and `Main` components: + ```bash + return ( + <> +
+
+