Building a recipes website using Gatsby and Flotiq
Tags: gatsby, javascript, tutorial, flotiq
Published: 2020-04-21 18:10:51

> This article was originally posted as a Flotiq [deep dive on using complex data structures](https://flotiq.com/docs/Deep-Dives/jamstack-recipes-website-complex-data-structures/)

## Introduction

When you're ready to take your headless CMS to the next level and start building data models that are a little more complex you'll find that standard, fixed data types will be too restrictive. Flotiq has always supported building relationships between Content Types, but sometimes that's not enough. 

In this article we'll discuss a couple of particular problems you might encounter when designing a data model and later - when working with it. Accidentally - we'll also build a **stunning website** with your favorite culinary recipes (scrambled eggs, of course!). 

![Recipes website built using Gatsby and Flotiq](https://editor.flotiq.com/images/flotiq-starter-recipes.png)

A simple `Recipe` model you might find useful for a recipe website could look like this:

* Name - text
* Slug - text
* Image - image
* Description - rich text
* **Ingredients** - rich text
* **Steps** - rich text
* Cooking time - number
* Servings - number

For such a model - Flotiq would generate a form looking like this:

![Flotiq form for a simple data model](https://flotiq.com/docs/Deep-Dives/images/jamstack-recipes-complex-data-structures/upload_5466699a3bcd1bdc5e419f2d17240c37.png)

and your API docs would describe that model this way:

![Flotiq API docs for a simple data model](https://flotiq.com/docs/Deep-Dives/images/jamstack-recipes-complex-data-structures/upload_0158c43f8d5cc1154fddd8ae68a15ae9.png)

This model might be acceptable for very simple websites, but having the `Ingredients` and `Steps` entered as unstructured text (even if using HTML `<li>`) will soon become an issue. 

Here's why:

1. No easy, programmatic, access to ingredients - eg. no way to build a shopping list out of it
2. Can't easily iterate through the recipe's steps - difficult to build an interactive UI, doesn't help with SEO either
3. People editing the content will use different formatting every time and the content will quickly become messy. You'll get entries like:

```
    2 eggs
    1 pinch of salt
    1 tbsp of butter
```

```
- Eggs: 2
- Salt: 1 pinch
- Butter: 1 tbsp
```

```
<ul>
    <li>2 eggs</li>
    <li>1 pinch of salt</li>
    <li>1 tablespoon of butter</li>
</ul>
```

and so on.



## Solution


The problem of unstructured data can be solved using repeatable content fragments defined directly in a data model. It's a simple and convenient solution - both for developers modeling data and content editors as well.

Here's how you would go about it with Flotiq's `list` data type:

![Flotiq's list data type](https://flotiq.com/docs/Deep-Dives/images/jamstack-recipes-complex-data-structures/upload_9ecd3721c970774c2735a195ff55643f.png)


Benefits:

* Less mess, providing structure without the need to create additional content types.
* The `list` data type will render as a set of sub-forms - makes it easier for content editing.
* Easier data access from the API - more readable data structure.
* Easier to interpret complex data on the frontend.

## Use case: Recipe content type


Now - let's apply the `list` data type to the recipes Content Type. Let's assume each step  will include a description and an optional image and every ingredient - it's amount, unit, product name.

We can now extend the example mentioned above:

* Name - text
* Slug - text
* Image - image
* Description - richtext
* **Ingredients - a list of:**
    * amount - number
    * unit - text
    * product - text
* **Steps - a list of:**
    * description - textarea
    * image - image
* Cooking time
* Servings

Your Content Type definition in Flotiq would then look like this:

![Recipe content type definition using lists](https://flotiq.com/docs/Deep-Dives/images/jamstack-recipes-complex-data-structures/upload_7d565cfe5f5df4287c3d7e0d7004fc94.png)

and you would expect this in the API docs:

![Recipe API docs showing lists](https://flotiq.com/docs/Deep-Dives/images/jamstack-recipes-complex-data-structures/upload_769871eca6460389041c8c52c381826f.png)

> Yup, we know, we're drooling over Flotiq's API docs every time, too. And you know what? You don't need to write a line of code - the docs, just as your entire RESTful API are generated every time you change your model definitions!

And this is how the form for that Content Type would render:

![Flotiq form for a content object using lists](https://flotiq.com/docs/Deep-Dives/images/jamstack-recipes-complex-data-structures/upload_a99534a9bf1aee346e58aec39037bfd5.png)

We used the `list` datatype in this [Gatsby & Flotiq recipes starter](https://github.com/flotiq/gatsby-starter-recipes) and you can see the results [here](https://flotiq-starter-recipes.herokuapp.com/). With this data model it's now really simple for a frontend developer to interpret that content on the website.

![Full example of a recipe using Flotiq lists](https://flotiq.com/docs/Deep-Dives/images/jamstack-recipes-complex-data-structures/upload_7dd4947f6433fabfaf9c94170b445dc4.png)

## Experiment with the Gatsby starter

If you'd like to dig a little deeper into this recipe website, here's your quickstart:
1. **Install gatsby**
    ```bash
    npm install -g gatsby
    ```
1. **Start project from the template using Gatsby CLI**
    
    ```bash
    gatsby new gatsby-starter-recipes https://github.com/flotiq/gatsby-starter-recipes.git
    ```
1. **Setup "Recipe" Content Type in Flotiq**

   Create your [Flotiq.com](https://flotiq.com) account. Next, create the `Recipe` Content Type:

   ![Recipe content type in flotiq](https://github.com/flotiq/gatsby-starter-recipes/raw/master/docs/create-definition-recipe.png)
    
   _Note: You can also create `Recipe` using [Flotiq REST API](https://flotiq.com/docs/API/)._ 

4. **Configure application**

    The next step is to configure our application to know from where it has to fetch the data.
       
    You need to create a file called `.env` inside the root of the directory, with the following structure:

    ```
    GATSBY_FLOTIQ_BASE_URL="https://api.flotiq.com"
    FLOTIQ_API_KEY="YOUR FLOTIQ API KEY"
    ```

5.  **Launch the Gatsby project**

    Navigate into your new site’s directory and start it up.

    ```sh
    cd gatsby-starter-recipes
    npm install
    gatsby develop
    ```
   
6.  **Open the source code and start editing!**
    
    Your site is now running at `http://localhost:8000`!

## Conclusions

Flotiq's list data type is an extremely easy to use solution for structuring your data. It organizes the content and makes it easy for content editors to build content, at the same time it's fully supported in the API and API docs. 

Go play with the recipe website project - we've shared a Gatsby starter for that:

* [Gatsby starter recipes - GitHub](https://github.com/flotiq/gatsby-starter-recipes)
* [Gatsby starter recipes - deployed on Heroku](https://flotiq-starter-recipes.herokuapp.com)