voorhoede / head-start

Base setup on top of headless services to help you quickly start a new website
ISC License
3 stars 0 forks source link

Paginate Page Query #74

Closed jbmoelker closed 7 months ago

jbmoelker commented 7 months ago

DatoCMS limits a collection in a GraphQL query to 100 records. This is an issue for the current getStaticPaths() function in src/pages/[locale]/[slug]/index.astro as method used does not account for having more than 100 page records. So we should probably create a dedicated DatoCMS helper to get all records in a collection, using pagination.

When querying records of a specific model you can supply arguments that allow you to paginate the query response. Pagination allows you to request a certain amount of records at the same time. The default limit is 20 records, and the maximum is 100. Pagination in DatoCMS docs

jbmoelker commented 7 months ago

We could add a helper function to src/lib/datacms.ts with something like this:

export const datocmsCollection = async ({ collection, fragment }) => {
  const { meta } = await datocmsRequest({
   query: `
      query ${collection}Meta {
        meta: _all${collection}Meta { count }
      }
   `
  });

  const recordsPerPage = 100;
  const totalPages = Math.ceil(meta.count / recordsPerPage);
  const records = [];

  for (let page = 0; page < totalPages; page++) {
    const data = await datocmsRequest({
      query: `
        query All${collection} {
          ${collection}: all${collection} (
             first: ${recordsPerPage}, 
             skip: ${page * recordsPerPage}
          ) {
            ${fragment}
          }
        }
      `
    });
    records.push(data[collection]);
  }

  return records;
}

And use it like this:

export async function getStaticPaths() {
  const data = await datocmsCollection({
    collection: 'Pages',
    fragment: `
      slugs: _allSlugLocales {
        locale
        value
      }
    `
  });

  return data.Pages.flatMap(page => page.slugs.map((slug) => ({
    params: { locale: slug.locale, slug: slug.value }
  })));
}