Lesson 9 - Adding remote data

Course
Learn Eleventy From Scratch
Module
Let’s build a website

Data doesn’t have to be local and static. Using the power of JavaScript data files, we’re going to pull in some remote data and render it on a template.


We talked about data in lesson 7. In this lesson, we’re going to build on that knowledge, looking at how JavaScript data files enable us to grab remote data and make it as accessible to our templates as static data like site.json.

Why would we want to grab remote data though? Being able to work with remote data opens all sorts of opportunities to make our site more dynamic. It lets us use Eleventy as a front-end for a content management system. This capability empowers teams to make incredibly fast front-ends for websites that have complex, heavy content systems, which were previously quite slow.

Having the benefits of both dynamic remote data and speed from static files really puts us in a good position to deliver a solid, performant user experience.

Grabbing our data permalink

First up, let’s take a look at the data we’re grabbing. In a new browser tab, go to https://11ty-from-scratch-content-feeds.piccalil.li/media.json. You should see something that looks like this:

Code language
Diff - don’t copy
{
  "items": [
    {
      "alt": "A notepad, mechanical pencil, phone and plant on very brightly lit desk",
      "large": "https://11tyfromscratch.imgix.net/notepad.jpg?w=1700&q=60&auto=format",
      "medium": "https://11tyfromscratch.imgix.net/notepad.jpg?w=890&q=60&auto=format",
      "small": "https://11tyfromscratch.imgix.net/notepad.jpg?w=600&q=60&auto=format",
      "credit": "https://unsplash.com/photos/bU6JyhSI6zo"
    },

    // The other items ommitted for brevity
}

We’re grabbing a collection of images that show off our pretend agency’s pretend studio.

The first thing we need to do is add a library that gives our Node environment a fetch method. That library is node-fetch.

In your terminal, in eleventy-from-scratch, run the following:

Code language
bash
npm install node-fetch

Once that’s installed, create a new file inside your _data folder called studio.js and add the following to it:

Code language
JavaScript
const fetch = require('node-fetch');

module.exports = async () => {
  try {
    const res = await fetch(
      'https://11ty-from-scratch-content-feeds.piccalil.li/media.json'
    );
    const {items} = await res.json();

    return items;
  } catch (ex) {
    console.log(ex);
    return [];
  }
};

This fetches the data from our endpoint using async/await, then when it’s loaded, it returns the items using destructuring.

Because JavaScript data files support async functions, we can still access this data, using {{ studio }} in our templates. Pretty rad, right?

This is cool, but let’s make it even cooler.

Because we’re pulling data from a remote source: every time you re-build the site, it will go and fetch it. This isn’t ideal—especially if you’re using a rate-limited API. Let’s say the API you’re pulling data from only allows 10 queries per hour. If you save your project 10 times in that hour, it’ll stop you from grabbing the data you need.

We’re going to mitigate this risk by using an even better library than node-fetch to do this for us. It’s made by Eleventy and it’s called @11ty/eleventy-cache-assets.

What this library does is fetch that remote data and cache it for a user-defined amount of time. Because this is a feed of images, it probably won’t change much, so we’re going to cache ours for 1 day. When that cache expires, it’ll go ahead and grab the remote data again.

To get this library running, we need to do some housekeeping first. Inside eleventy-from-scratch, run the following command in your terminal:

Code language
bash
npm uninstall node-fetch

Then, run the following command:

Code language
bash
npm install @11ty/eleventy-cache-assets

That cleans out the fetch library we were using and installs the cache library we’re going to use instead.

Now, open up eleventy-from-scratch/src/_data/studio.js again and delete everything.

Replace that deleted code with this:

Code language
JavaScript
const Cache = require('@11ty/eleventy-cache-assets');

/**
 * Grabs the remote data for studio images and returns back
 * an array of objects
 *
 * @returns {Array} Empty or array of objects
 */
module.exports = async () => {
  try {
    // Grabs either the fresh remote data or cached data (will always be fresh live)
    const {items} = await Cache(
      'https://11ty-from-scratch-content-feeds.piccalil.li/media.json',
      {
        duration: '1d', // 1 day
        type: 'json'
      }
    );

    return items;
  } catch (ex) {
    console.log(ex);

    // If failed, return back an empty array
    return [];
  }
};

This is essentially the same as code as before, but we destructure the items straight out of the Cache instead this time, which simplifies things a bit.

Rendering our new data permalink

Now we have our data, it works exactly the same as other data files. Let’s put that into practice by adding a studio feed to our home page.

First up: in your partials folder, create a new file called studio-feed.html and add the following HTML to it:

Code language
HTML
{% if studio.length %}
<article class="[ studio-feed ] [ dot-shadow panel ] [ bg-tertiary-glare ]">
  <div class="[ wrapper ] [ flow flow-space-300 ]">
    <h2
      class="[ studio-feed__heading ] [ headline ] [ md:measure-micro ]"
      data-highlight="secondary"
    >
      {{ studioFeed.title }}
    </h2>
    <p class="visually-hidden" id="studio-feed-desc">
      A collection of images from around our studio and the people who work here.
    </p>
    <div class="[ studio-feed__items ] [ flow-space-700 ]">
      <ul class="studio-feed__list">
        {% for item in studio %}
        <li>
          <img
            src="{{ item.medium }}"
            alt="{{ item.alt }}"
            draggable="false"
            class="radius"
          />
        </li>
        {% endfor %}
      </ul>
    </div>
  </div>
</article>
{% endif %}

This looks familiar, right? We first determine if the  {{ studio }} variable has a length. We do this because the function that grabs our remote data returns an empty array in its catch statement. This means there could be nothing to loop, so what we don’t want to do is render empty elements. After that check has completed, we loop through each item and render the image.

The chances that your remote data source returning nothing or throwing an error are probably quite slim, but the important message here is that we make sure our website degrades gracefully if this does happen. It’s helpful to be proactive where you see potential risk—especially with display logic like this example.

Let’s add this partial to the home page. Open up eleventy-from-scratch/src/_includes/layouts/home.html. After the featured work partial ({% include "partials/featured-work.html" %}), add the following:

Code language
HTML
{% include "partials/studio-feed.html" %}

Lastly, open up eleventy-from-scratch/src/index.md and add the following Front Matter to your existing items:

Code language
text
studioFeed:
  title: 'From inside the studio'

Job done. You’ve now got some remote data on your home page. If you open up http://localhost:8080 and scroll down, you should see something that looks like this:

The addition of various hipster studio images on the home page

Wrapping up permalink

You should be feeling bloody awesome right now. Pulling in remote data into a static website is cool as heck and you just did it.

Next up, a recap of where we’re at because our home page is pretty much done.

Next up: Lesson 10 - Home page complete and recap

We’ve achieved a heck of a lot over the last 9 lessons so let’s gather round and recap what we’ve learned.

Get started

Help! My version of this lesson isn’t working.

Don’t panic, you can download the working project here! Once they are downloaded: replace your project with these files and run npm install. You can read more information here.

Download project files

Hello, I’m Andy and I’ll help you build fast, accessible websites & design systems.

I’m a freelance CSS and design systems consultant, based in the UK. I specialise in design systems and creative web design, such as landing pages and campaign work.

I’m currently helping Google by refactoring the CSS and creating a design system for web.dev, but I have availability for projects such as small websites, landing pages and consultancy. I will have full availability for larger projects in January 2022.

Hire me