Getting Started with 11ty
This integration guide follows the Quick Start Guide and assumes you have you have fully completed the "Hands-on" path. You should be able to consume the API by browsing the URL http://localhost:1337/api/restaurants.
If you haven't gone through the Quick Start Guide, the way you request a Strapi API with 11ty remains the same except that you do not fetch the same content.
Create an 11ty app
Create a package.json file, install and save Eleventy into your project.
- yarn
- npm
yarn init -y
yarn add @11ty/eleventy
npm init -y
npm install @11ty/eleventy
Confirm the installation went ok:
npx @11ty/eleventy
# Wrote 0 files in 0.02 seconds (v0.11.0)
Configure 11ty
11ty does not create any file structure for you. It's up to you to do it.
- Create a ./src/_datafolder containing acategories.jsand arestaurants.jsfile. They will be used to fetch your content from Strapi.
- Create a ./src/_templatesfolder containing adefault.liquidfile. It will be the default template of your project.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta content="width=device-width, initial-scale=1.0" name="viewport" />
    <title>
      {{ renderData.title }}
    </title>
  </head>
  <body>
    <a href="/">Home</a>
    {{ content }}
  </body>
</html>
- Create a ./src/index.md,./src/restaurant.mdand a./src/category.mdfile. They will define how you'll present the data.
- Create a .eleventy.jsfile containing the following (make sure to prefix the file's name with the dot):
const HtmlMin = require('html-minifier');
const ErrorOverlay = require('eleventy-plugin-error-overlay');
module.exports = eleventyConfig => {
  eleventyConfig.setTemplateFormats(['md']);
  eleventyConfig.addPlugin(ErrorOverlay);
  eleventyConfig.addTransform('htmlmin', (content, outputPath) => {
    if (outputPath.endsWith('.html')) {
      let minified = HtmlMin.minify(content, {
        useShortDoctype: true,
        removeComments: true,
        collapseWhitespace: true,
      });
      return minified;
    }
    return content;
  });
  return {
    dir: {
      input: 'src',
      output: 'dist',
      includes: '_templates',
      data: '_data',
    },
    jsDataFileSuffix: '.data',
  };
};
- Finally, add the following packages to your application:
- yarn
- npm
yarn add axios eleventy-plugin-error-overlay html-minifier
npm install axios eleventy-plugin-error-overlay html-minifier
GET Request your collection type
Execute a GET request on the restaurant collection type in order to fetch all your restaurants.
Be sure that you activated the find permission for the restaurant collection type.
const { default: axios } = require('axios');
module.exports = async () => {
  try {
    const res = await axios.get('http://localhost:1337/api/restaurants?populate=*');
    return res.data;
  } catch (error) {
    console.error(error);
  }
};
{
    "data": [
        {
            "id": 1,
            "attributes": {
                "name": "Biscotte Restaurant",
                "description": "Welcome to Biscotte restaurant! Restaurant Biscotte offers a cuisine based on fresh, quality products, often local, organic when possible, and always produced by passionate producers.",
                "createdAt": "2022-05-23T09:41:46.762Z",
                "updatedAt": "2022-05-23T09:44:32.424Z",
                "publishedAt": "2022-05-23T09:44:32.423Z",
                "categories": {
                    "data": [
                        {
                            "id": 2,
                            "attributes": {
                                "name": "Brunch",
                                "createdAt": "2022-05-23T09:42:16.764Z",
                                "updatedAt": "2022-05-23T09:44:21.534Z",
                                "publishedAt": "2022-05-23T09:44:21.532Z"
                            }
                        }
                    ]
                }
            }
        }
    ],
    "meta": {
        "pagination": {
            "page": 1,
            "pageSize": 25,
            "pageCount": 1,
            "total": 1
        }
    }
}
Example
./src/_data/restaurants.js
const { default: axios } = require('axios');
module.exports = async () => {
  try {
    const res = await axios.get('http://localhost:1337/api/restaurants?populate=*');
    return res.data;
  } catch (error) {
    console.error(error);
  }
};
./src/index.md
---
title: Restaurants
layout: default.liquid
pagination:
  data: restaurants.data
  size: 100
  alias: restaurants
---
# Restaurants
<ul>
{%- for restaurant in restaurants -%}
  <li><a href="/restaurants/{{ restaurant.id }}/">{{ restaurant.attributes.name }}</a></li>
{%- endfor -%}
</ul>
./src/restaurant.md
---
title: Restaurant
layout: default.liquid
pagination:
  data: restaurants.data
  size: 1
  alias: restaurant
permalink: 'restaurants/{{ restaurant.id }}/'
---
# {{ restaurant.attributes.name }}
{{ restaurant.attributes.description }}
## Categories
{% for category in restaurant.attributes.categories.data %}
  <li><a href="/categories/{{ category.id }}/">{{ category.attributes.name }}</a></li>
{% endfor %}
Execute a GET request on the category collection type in order to fetch a specific category with all the associated restaurants.
Be sure that you activated the find permission for the category collection type.
const { default: axios } = require('axios');
module.exports = async () => {
  try {
    const res = await axios.get('http://localhost:1337/api/categories?populate=*');
    return res.data;
  } catch (error) {
    console.error(error);
  }
};
{
    "data": [
        {
            "id": 1,
            "attributes": {
                "name": "French Food",
                "createdAt": "2022-05-23T09:42:04.679Z",
                "updatedAt": "2022-05-23T09:44:25.309Z",
                "publishedAt": "2022-05-23T09:44:25.308Z",
                "restaurants": {
                    "data": []
                }
            }
        },
        {
            "id": 2,
            "attributes": {
                "name": "Brunch",
                "createdAt": "2022-05-23T09:42:16.764Z",
                "updatedAt": "2022-05-23T09:44:21.534Z",
                "publishedAt": "2022-05-23T09:44:21.532Z",
                "restaurants": {
                    "data": [
                        {
                            "id": 1,
                            "attributes": {
                                "name": "Biscotte Restaurant",
                                "description": "Welcome to Biscotte restaurant! **Restaurant Biscotte** offers a cuisine based on fresh, quality products, often local, organic when possible, and always produced by passionate producers.",
                                "createdAt": "2022-05-23T09:41:46.762Z",
                                "updatedAt": "2022-05-23T09:44:32.424Z",
                                "publishedAt": "2022-05-23T09:44:32.423Z"
                            }
                        }
                    ]
                }
            }
        }
    ],
    "meta": {
        "pagination": {
            "page": 1,
            "pageSize": 25,
            "pageCount": 1,
            "total": 2
        }
    }
}
Example
./src/_data/categories.js
const { default: axios } = require('axios');
module.exports = async () => {
  try {
    const res = await axios.get('http://localhost:1337/api/categories?populate=*');
    return res.data;
  } catch (error) {
    console.error(error);
  }
};
./src/category.md
---
title: Category
layout: default.liquid
pagination:
  data: categories.data
  size: 1
  alias: category
permalink: 'categories/{{ category.id }}/'
---
# {{ category.name }}
## Restaurants
{% for restaurant in category.attributes.restaurants.data %}
<li><a href="/restaurants/{{ restaurant.id }}/">{{ restaurant.attributes.name }}</a></li>
{% endfor %}
You can find your restaurants and categories by browsing http://localhost:8081/restaurants/<id-of-restaurant> and http://localhost:8081/categories/<id-of-category>.
User Stories
- How Paradigma Digital switched from Wordpress to Strapi and Eleventy.