jsonhttpaxiosshopify

Get ALL Shopify Products


I'm trying to get a JSON of all of the products from a Shopify store. I've been making a GET request to the

{STORE URL}/products.json

endpoint. But this ends up only showing a portion of the products offered by the store (a lot, but not all). When I change the parameters to:

{STORE URL}/products.json?limit=20000000

I get more products but still not all. I doubt sites are selling more than 20 million products. I'm also using Axios btw. Please let me know if you know why this happens and how to get a complete list of products, variants, and more.


Solution

  • You can't get more than 250 products with a single request from Shopify.

    Refer to the docs here: https://shopify.dev/docs/admin-api/rest/reference/products/product?api[version]=2020-04 ( where the limit max value can be 250 )

    In order to get more than 250 products you need to make a recursive function and use the page_info argument to make paginated requests. More on the matter can be seen here: https://shopify.dev/tutorials/make-paginated-requests-to-rest-admin-api

    When you make a request and there is a pagination shopify returns a header similiar to this one:

    Link: "<https://{shop}.myshopify.com/admin/api/2019-07/products.json?page_info=vwxyzab&limit=6>; rel=next"
    

    In order to make a request to the second page you need to grab the link and make a request to it, the same applies when you make that request, there will be the same header if there are more pages and so on.

    So you need to get your response header and the link from it and make it recursive:

    function makeRequest(nextLink = '{STORE URL}/products.json?limit=250'){
      return new Promise((resolve, reject) => {
        fetch(nextLink).then(r => {
          const headerLink = r.headers.get('link');
          const match = headerLink.match(/<[^;]+\/(\w+\.json[^;]+)>;\srel="next"/);
          const nextLink = match ? match[1] : false;
          if(nextLink){
            makeRequest(nextLink)
          } else {
            resolve();
          }
        })
      })
    }