Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to limit and skip after grouping in a GraphQL query to paginate the tags list page?

Tags:

I'm trying to paginate the blog tags list page in a Gatsby site, the tags are defined in the frontmatter of the MDX files:

---
title: Blog Post Title
date: 2020-05-20
tags: ["Markdown", "Gatsby", "JavaScript"]
---

Paginating the posts is easy using limit and skip passed in the page context object:

query Posts($limit: Int!, $skip: Int!) {
  allMdx(
    sort: { fields: frontmatter___date, order: DESC }
    limit: $limit
    skip: $skip
  ) {
    nodes {
      ...
  }
}

But this doesn't apply for paginating the tags list page, this is going to limit and skip on allMdx, so we're going to get the same tag on multiple pages and also the totalCount is not going to be the total posts for a tags but the total for the limited posts.

query Tags($limit: Int!, $skip: Int!) {
  allMdx(limit: $limit, skip: $skip) {
    group(field: frontmatter___tags) {
      fieldValue
      totalCount
    }
  }
}

So how can I apply limit and skip on the group and not on the posts? What I can do is get all the tags for each page and use limit and skip in the component to show only the current page's tags, but I don't think this is the best way to do it.

like image 1000
Pierre Avatar asked May 20 '20 13:05

Pierre


1 Answers

During iteration over pages (where create page is used) you can create tag nodes.

  • create an empty tags object (before iteration, for by name addressing),
  • in loop (for every page):
    • loop over page tags (from frontmater tags):
      • create tags[tag_name] object (if not exists) with posts array property;
      • insert current page slug into tags[tag_name].posts

At the end (after create page loop) you have data collected in the structure like:

tags={
  "tag_1" : {
    posts [
      "slug_1",
      "slug_2"
    ]
  },
  "tag_2" : {
    posts [
      "slug_2",
      "slug_3",
      "slug_4"
    ]
  }
}

By iteration over this object you can create tag nodes with {tag_name, posts, post_count}.

After this you can create /tags pages. You can query for nodes collection.

You should be able (test in playground) to paginate them for tags index pages, you can display tag name, amount of pages and even pages links (expand amount component view? posts and post_count passed as props).

like image 103
xadm Avatar answered Sep 30 '22 20:09

xadm