# Lesson 9: Adding remote data
We talked about data in lesson 7. In this lesson, we’re going to build on that knowledge, looking at how JavaScript data files (opens new window) 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
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 (opens new window). You should see something that looks like this:
{
"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 omitted 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 (opens new window). That library is node-fetch (opens new window).
In your terminal, in eleventy-from-scratch
, run the following:
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:
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:
npm uninstall node-fetch
Then, run the following command:
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:
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
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:
{% 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.
TIP
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:
{% include "partials/studio-feed.html" %}
Lastly, open up eleventy-from-scratch/src/index.md
and add the following Front Matter to your existing items:
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 (opens new window) and scroll down, you should see something that looks like this:
# Wrapping up
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.
:::