Skip to main content

Eleventy
Build a Static Site with Backend Data Handling



.eleventy.js

// AZUL CODING ---------------------------------------
// Eleventy - Build a Static Site with Backend Data Handling
// https://youtu.be/71q-C9BVUng


module.exports = function (eleventyConfig) {

    eleventyConfig.addNunjucksFilter("trimText", function(text) {
        if (text.length >= 40)
            return text.substring(0, 40) + "...";
        else
            return text;
    });

    eleventyConfig.addNunjucksFilter("filterComments", function(comments, postID) {
        return comments.filter(x => x.postId == postID);
    });

    eleventyConfig.addNunjucksFilter("exclude", function(posts, excluded) {
        return posts.filter(x => excluded.indexOf(x.id) == -1);
    });

    return {
        dir: {
            input: "src",
            output: "_site",
        },
    };
};

Enjoying this tutorial?


index.njk

---
title: "Posts - Azul Coding"
layout: "base.njk"
---

<!-- AZUL CODING --------------------------------------- -->
<!-- Eleventy - Build a Static Site with Backend Data Handling -->
<!-- https://youtu.be/71q-C9BVUng -->


        {% for post in posts | exclude(excluded) %}
        <a class="card" href="/post/{{ post.id }}">
            <div class="content">
                <div class="text-overlay">
                    <h2>Post {{ post.id }}</h2>
                    <p>{{ post.title | trimText }}</p>
                </div>
            </div>
        </a>
        {% endfor %}

post.njk

---
title: "Post - Azul Coding"
pagination:
    data: posts
    size: 1
    alias: post
permalink: "post/{{ post.id }}/"
layout: "base.njk"
---

<!-- AZUL CODING --------------------------------------- -->
<!-- Eleventy - Build a Static Site with Backend Data Handling -->
<!-- https://youtu.be/71q-C9BVUng -->


        <div class="post-container">
            <h2>Post {{ post.id }}</h2>
            <p>{{ post.title }}</p>
            <p>{{ post.body }}</p>
            <p><a href="/">Go back</a></p>

            <h3>Comments</h3>
            <ul>
                {% for comment in comments | filterComments(post.id) %}
                <li>
                    <p>{{ comment.body }}</p>
                </li>
                {% endfor %}
            </ul>
        </div>

base.njk

<!-- AZUL CODING --------------------------------------- -->
<!-- Eleventy - Build a Static Site with Backend Data Handling -->
<!-- https://youtu.be/71q-C9BVUng -->


<!DOCTYPE html>
<html lang="en-GB">
    <head>
        <title>{{ title }}</title>
        <meta charset="utf-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <style>
            body {
                margin: 40px;
                background-color: #004961;
                display: flex;
                flex-wrap: wrap;
                gap: 25px;
            }
            * {
                font-family: 'Inter', sans-serif;
                color: white;
            }
            h2 {
                margin: 15px 0 5px 20px;
            }
            p {
                font-size: 16px;
                margin: 0 20px 20px 20px;
            }
            .card {
                width: 250px;
                height: 250px;
                background-color: #1576C1;
                border-radius: 15px;
                box-shadow: 0 0 10px rgb(0, 0, 0, 0.4);
                display: flex;
                text-decoration: none;
                transition: background-color 0.3s;
            }
            .card:hover {
                background-color: #2697EF;
            }
            .content {
                height: 100%;
                width: 100%;
                border-radius: 15px;
                display: flex;
            }
            .text-overlay {
                margin-top: auto;
                width: 100%;
                border-bottom-left-radius: 15px;
                border-bottom-right-radius: 15px;
                background-color: rgb(0, 0, 0, 0.3);
            }
            .post-container h3 {
                margin: 80px 0px 5px 20px;
            }
        </style>
    </head>
    <body>
        {{ content | safe }}
    </body>
</html>

data.js

// AZUL CODING ---------------------------------------
// Eleventy - Build a Static Site with Backend Data Handling
// https://youtu.be/71q-C9BVUng


const Cache = require("@11ty/eleventy-cache-assets");

module.exports = async function() {
    try {
        // Change this link to whatever you want, but bear in mind that 
        // the name of this file is its access key in the templates
        // e.g. the JSON returned in data.js would be accessed as {{ data }}
        
        return await Cache("https://jsonplaceholder.typicode.com/posts", {
            duration: "1d", // cached for one day
            type: "json"
        });

    } catch(e) {
        return {
            error: "An error occurred."
        };
    }
};