In our last article we used external data to render posts on our site.
If you noticed, we don't have that cool Previous/Next Post that was at the bottom of our posts before.
Wouldn't it be nice to have that back? That is the main focus of this article.
Let's first look at what our post pagination looked like before with local posts
{% set previousPost = collections.post | getPreviousCollectionItem(page) %}
{% set nextPost = collections.post | getNextCollectionItem(page) %}
{% if previousPost %}Previous: <a href="{{ previousPost.url }}">{{ previousPost.data.title }}</a>{% endif %}
<br>
{% if nextPost %}Next: <a href="{{ nextPost.url }}">{{ nextPost.data.title }}</a>{% endif %}
Above, we were making use of what I called one of the cornerstones of Eleventy - collections.
This method will not work for the posts we've fetched from Hashnode because they aren't part of a collection like the posts we had.
To bring that functionality back we will need to add a couple things to our .eleventy.js
A Collection
When we started this series we made a collection - for our pages. We are going to employ that same knowledge to make a collection from our Hashnode posts.
In .eleventy.js
add this:
eleventyConfig.addCollection("articles", async () => {
const endpoint = `https://api.hashnode.com/`;
const { GraphQLClient, gql } = require("graphql-request");
const client = new GraphQLClient(endpoint);
const query = gql`
{
user(username: "Psypher1") {
publication {
posts {
title
coverImage
brief
slug
dateAdded
contentMarkdown
}
}
}
}
`;
const articles = await client.request(query);
return articles.user.publication.posts;
});
We have used the same piece of code that we had in our posts.js
file, but this time to create a collection.
A Filter
In our original code we also had this filter: getPreviousCollectionItem(page)
- this is what gets us the next and previous functionality.
For that, we will also make a filter in the same .eleventy.js
file
elevntyConfig.addFilter("nextArticle", (articles, page, modifier = 1) => {
const parts = page.outputPath.split("/");
parts.pop(); // get rid of `index.html`
const slug = parts.pop();
for (const [index, article] of articles.entries()) {
const target = index + modifier;
if (article.slug === slug && target >= 0 && target < articles.length) {
return articles[target];
}
}
});
What we have done now works beacuse:
The data (articles) returned in the collection sort of guides how next/previous are going to work
Paginate Partial
Then we will change/create our _paginate.njk
file to look like this:
{% set previousPost = collections.articles | nextArticle(page) %}
{% set nextPost = collections.articles | nextArticle(page, -1) %}
{% if previousPost %}Previous: <a href="/blog/{{ previousPost.slug }}">{{ previousPost.title }}</a>{% endif %}
<br>
{% if nextPost %}Next: <a href="/blog/{{ nextPost.slug }}">{{ nextPost.title }}</a>{% endif %}
Then we come into our postLayout.njk
file and include it at the bottom
{% include "partials/_paginate.njk" %}
And there we go. We are back where we were.
Special thanks goes to Shiv Jha-Mathur from the Eleventy Discord who provided the guidance and solution to this particular conundrum.
My Quest For You
Now that we've seen how we can fetch articles from an API and still have the same functionality we had with local ones. Try to see how you can combine everyhing we've learnt in the series into one complete site.
In the meantime, I will work on updating the series repo - do the different branches per part thing.
Wish me luck 😄
Thank you for reading, let's connect!
Thank you for visiting this little corner of mine. Let's connect on Twitter, Polywork and LinkedIn
Top comments (6)
Hey @psypher1 , it was very nice to follow through your 11ty series. Thank you for making the effort and writing it down!!
I am planning to use 11ty for a content heavy project, but no interaction. These tutorial gave a good base to start!
Hello there 😁... I'm glad the series was useful to you and it's my pleasure I'm able to help. I did it to answer questions I had - I learn best by doing.
Oh you are ? That's great! I would really like to see what you build. Please share the link when it's live
Yes, I learn too by doing. With 11ty I got stuck because the official documentation jumps round topics. I need a linear, progressive structure to understand it.
I was working on my design portfolio website: ladislavszolik.com/ I realized, if I want to appeal to companies which value design, I need a super clean, performant portfolio site.
Ah yeah, the 11ty docs... The jumping around was also a reason I did this... I got more information from asking people than from the docs. I should bring this up in the discord.
That's a really good approach. Your site looks clean, I like how it's straight to the point. Also you're very good at what you do.
I've been with working on a reimagining of my site. I'll be borrowing your individual project breakdown - it never crossed my mind to that.
Thank you
Thanks, appreciate it! Yeah, feel free to borrow anything which works.
Design hiring manager often look for the process and the thoughts behind.
Btw, maybe you should include WebC into your tutorials ;-)
Absolutely.... That makes a lot of sense. The projects I showcase would benefit from a process section
I definitely will add WebC, I've had my eye on it since its inception. I'm just waiting for it to settle first