I want to fetch the sellingPlanAllocations of multiple variants at once. SellingPlanAllocations can be fetched only through the Storefront API but it does not allow querying productVariants directly. So, one has to query Storefront API with this hierarchy: products → variants → sellingPlanAllocations. This query would involve nested resources and there is no standard way to paginate correctly between the nested resources.
Hence, I tried to use the nodes query supplying the list of variant IDs and fetching sellingPlanAllocations through them. As this would involve only one level of hierarchy (variants → sellingPlanAllocations), I was confident of handling the pagination. However, to my surprise, the pagination did not work in this case.
query GetVariantSellingPlanAllocations {
nodes(ids: ["gid://shopify/ProductVariant/<variant-id>", ]){
__typename
... on ProductVariant {
id
title
sellingPlanAllocations(after: null, first:3) {
nodes {
sellingPlan {
id
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
I tried the above query with a variant that has 5 allocations. The first iteration returned 3 allocations. The hasNextPage value in the pageInfo was true and I used the endCursor from this output and supplied it as the value to the after parameter on the sellingPlanAllocations and executed the query again. It returned the exact same output as the previous query with the same 3 allocations and the same pageInfo again. This basically means the after value supplied in the second query was not honoured by the server.
To eliminate the fact that it is a limitation of the nodes query, I used the same pattern on a query with product and variants and the pagination worked fine with that.
query productsPagination {
nodes(ids: ["gid://shopify/Product/<product-id>", ]){
__typename
... on Product {
id
title
variants(first:1, after: null) {
nodes {
id
title
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
Pagination not working with the first query (variants → sellingPlanAllocations) - is it something related to the fact that the variants are not allowed to be queried directly ?
1 Like
Use the product query instead of nodes:
graphql
query GetVariantSellingPlanAllocations($variantId: ID!, $after: String) {
product(id: "gid://shopify/Product/<product-id>") {
variant(id: $variantId) {
id
title
sellingPlanAllocations(first: 3, after: $after) {
nodes {
sellingPlan {
id
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
For multiple variants: Make separate queries per variant or use query batching/aliasing:
graphql
query GetMultipleVariants($after1: String, $after2: String) {
product(id: "gid://shopify/Product/<product-id>") {
variant1: variant(id: "gid://shopify/ProductVariant/<id1>") {
sellingPlanAllocations(first: 3, after: $after1) { ... }
}
variant2: variant(id: "gid://shopify/ProductVariant/<id2>") {
sellingPlanAllocations(first: 3, after: $after2) { ... }
}
}
}
The nodes query doesn’t properly handle cursor-based pagination on nested connections—this is a known limitation, not related to variants specifically but to how nodes processes connection arguments.
Hi Mustafa,
Thanks a lot for your response.
Like I my mentioned in my original post, the nodesquery handles pagination correctly if I use it on products → variants (the query shared below).
query productsPagination {
nodes(ids: ["gid://shopify/Product/<product-id>", ]){
__typename
... on Product {
id
title
variants(first:1, after: null) {
nodes {
id
title
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
It doesn’t work for variants → sellingPlanAllocations. I was planning to use the variants → sellingPlanAllocations query with variant ids in batches of 250 across different products which would make use of batching/aliasing difficult.
hey @sriram-1 try this one plz
I understand your situation now. You want to use the nodes query to fetch sellingPlanAllocations for variants across multiple products, but pagination isn’t working correctly at the sellingPlanAllocations level.
Here’s the perfect solution using a hybrid approach:
Solution: Two-Step Approach with Bulk Operations
Since nodes query doesn’t handle pagination properly for variants → sellingPlanAllocations, use this approach:
Step 1: Use nodes query to get variant IDs (works fine)
graphql
query getVariantIds {
nodes(ids: ["gid://shopify/Product/<product-id-1>", "gid://shopify/Product/<product-id-2>"]) {
__typename
... on Product {
id
title
variants(first: 250) {
nodes {
id
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
Step 2: Fetch sellingPlanAllocations using individual variant queries with aliases
graphql
query getSellingPlanAllocations {
variant1: node(id: "gid://shopify/ProductVariant/<variant-id-1>") {
... on ProductVariant {
id
sellingPlanAllocations(first: 10) {
edges {
node {
id
sellingPlan {
id
name
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
variant2: node(id: "gid://shopify/ProductVariant/<variant-id-2>") {
... on ProductVariant {
id
sellingPlanAllocations(first: 10) {
edges {
node {
id
sellingPlan {
id
name
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
# ... up to 250 aliases (within query complexity limits)
}
Alternative: Use Bulk Operations API (RECOMMENDED)
For large-scale data fetching, Shopify’s Bulk Operations API is ideal:
graphql
mutation {
bulkOperationRunQuery(
query: """
{
products {
edges {
node {
id
title
variants {
edges {
node {
id
title
sellingPlanAllocations {
edges {
node {
id
sellingPlan {
id
name
}
}
}
}
}
}
}
}
}
}
}
"""
) {
bulkOperation {
id
status
}
userErrors {
field
message
}
}
}
Check status and download results:
graphql
query {
currentBulkOperation {
id
status
errorCode
createdAt
completedAt
objectCount
fileSize
url
partialDataUrl
}
}
Why This Works
- Bulk Operations API handles all pagination automatically and returns a JSONL file with all data
- No query complexity issues
- Perfect for batch processing variants across multiple products
- Handles sellingPlanAllocations pagination correctly
Implementation Pseudo-code
javascript
// 1. Trigger bulk operation
const bulkOp = await shopify.graphql(bulkMutation);
// 2. Poll for completion
while (status !== 'COMPLETED') {
await sleep(1000);
status = await checkBulkOperationStatus(bulkOp.id);
}
// 3. Download and parse JSONL file
const data = await fetch(bulkOp.url);
const jsonlLines = data.split('\n');
const parsedData = jsonlLines.map(line => JSON.parse(line));
This approach eliminates pagination complexity entirely and is Shopify’s recommended method for large dataset operations.
Thanks for your response, Mustafa.
I tried both the solutions and both of them don’t work for me unfortunately.
Solution 1 - The node query used on individual variants (in Step 2) suffers from the same issue - pagination on sellingPlanAllocations does not work.
Solution 2 - The bulk operations is available only with the Admin API and sellingPlanAllocations is not exposed through the Admin API.
Thanks for taking time to help me out.