Retrieving multiple products by ID using the AJAX API

Solved
Highlighted
Tourist
4 1 2

Hi, long story short, I need to use the (non-admin) AJAX API to get data for products using only their ID. I would use liquid but I don't have access to the product's handles, so that's not an option. I only have the IDs - I said it's a long story haha

From what I can tell the best way to do this is to use the "suggestions" API for...not exactly its intended purpose.

This works perfectly for fetching one product at a time:

 

 

fetch(`/search/suggest.json?type=product&q=id:${id}&resources[type]=product`).then(data => {
  console.log(data)
});

 

 

But it would be a huge waste of HTTP requests if I had to do this for every product on this page - not the end of the world, but very unideal. 

I'm wondering if there's a way for me to pass multiple IDs to return all the products at once. I can't find any documentation whatsoever for this "q" parameter other than it's supposed to be the query, but there's no syntax given for how the query should work. I tried passing `ids` instead of `id` with a comma-delimited list, and while the request went through, it came back with zero results. All other formats I've tried have resulted in a 500 error from the request.

Thanks in advance!

0 Likes
Highlighted
Shopify Partner
41 5 9

Can you put all of the products in a collection and fetch the whole collection using graphql?

0 Likes
Highlighted
Tourist
4 1 2

No graphql unfortunately, I'm working with a regular Shopify theme so all I have is liquid and JS.

0 Likes
Highlighted
Shopify Partner
41 5 9

@keithpickering You can create the collection though, right? I may have a couple of options for you.

0 Likes
Highlighted
Tourist
4 1 2

Yeah I can create a collection. It's a little cumbersome since we're already using a separate app for bundling the products (and it stores the bundle products by ID in some shop metafields) but it wouldn't be the end of the world. 

0 Likes
Highlighted
Shopify Partner
41 5 9

@keithpickering you can fetch graphql using vanilla Javascript. You will need to create a private app within your Shopify store by visiting <your-store>.myshopify.com/admin/apps/private. When you create the app, make sure that the only permission checked under Storefront API Permissions is Read products, variants, and collections. You can then do something like below:

const api_url = 'https://your-store.myshopify.com/api/2020-07/graphql';
const headers = new Headers({
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'X-Shopify-Storefront-Access-Token': 'your-access-token'
});

const getShopifyProducts = async () => {
  const response = await fetch(api_url, {
    method: 'POST',
    headers: headers,
    body: JSON.stringify({query: query()})
  });
  const Shop = await response.json();
  displayProducts(Shop.data.collectionByHandle.products.edges)
}

const query = () => `
  {
    shop {
      name
      primaryDomain {
        url
        host
      }
    }
    collectionByHandle(handle: "pomades") {
      id
      products(first: 10) {
        edges {
          node {
            title
            id
            priceRange {
              maxVariantPrice {
                amount
              }
              minVariantPrice {
                amount
              }
            }
            images(first: 5) {
              edges {
                node {
                  originalSrc
                  altText
                }
              }
            }
            variants(first: 100) {
              edges {
                node {
                  title
                  id
                  priceV2 {
                    amount
                  }
                  image {
                    originalSrc
                    altText
                  }
                }
              }
            }
          }
        }
      }
    }
  }
`

Above code running in a Code Pen 

Another option is to create an alternate collection view that doesn't render a layout using the {% layout none %} liquid tag. You can then fetch a string of html that you can append to another piece of html. This is a bit hacky, but I have done it. You can see it setup here. By requesting your-store.com/collections/collection-handle?view=products (products is the name of my alternate template), Shopify responds with a page that doesn't have any of your apps, styles or any other dependencies that are loaded in the regular layout.liquid file.

 

2 Likes
Highlighted
Shopify Partner
2294 116 341

You could also put the products into navigation menus and output specific pages in a <script> or in an alternate template.

Though making premade collections can be the sanest route since we cannot generate frontend collections.

For more than a handful of products use automatic collection based on tags.

shopify.com/collections/collectionname/products.json

 

Otherwise set an alternate template with no layout on /search and parse the terms returning text in json (cannot set mime type)

https://shopify.com/search?q=1234567890+0987654321&view=ajax

https://shopify.dev/docs/themes/liquid/reference/objects/search#search-terms

I can't find any documentation whatsoever for this "q" parameter other than it's supposed to be the query, but there's no syntax given for how the query should work. I tried passing `ids` instead of `id` with a comma-delimited list, and while the request went through, it came back with zero results. All other formats I've tried have resulted in a 500 error from the request.

If your up for experimenting with the q param observe other endpoints that use square brackets such as the /add endpoint

add/?items[0][id]=1234567890&items[0][quantity]=1&items[1][id]=0987654321&items[1][quantity]=1

 

 

Problem Solved? ✔️Accept and ? Like the solution so you can help others.
Buy me a coffee ☕ paypal.me/paulnewton or donate to eff.org
Confused? Busy? Buy a custom solution paull.newton+shopifyforum@gmail.com
0 Likes
Highlighted
Tourist
4 1 2

This is an accepted solution.

Thanks for the tip about GQL, I had no idea and it's really put me in the right direction. The documentation for this stuff hasn't helped me too much, but with a bunch of trial and error I have found a GQL query that allows me to obtain products by ID. The clincher is using `btoa` to encode the GID format into a base64 string, since the Storefront API doesn't seem to recognize the regular GIDs.

const gids = ids.map(id => btoa(`gid://shopify/Product/${id}`));
return `
  nodes(ids: ${JSON.stringify(gids)}) {
    ...on Product {
      id
      title
    }
  }
}
`;
2 Likes