Extract structured product information from any Presentéum collection, predictive search result, or individual product JSON endpoint. Collection extraction includes product URLs, titles, prices, availability, visible description text, product types, and image URLs. Search extraction returns matching product titles and URLs plus available metadata. Individual product extraction is useful for checking a specific tile's product metadata and variant availability before investigating shipping eligibility.
Use Cases
Use when the caller provides a Presentéum collection handle or collection URL and needs the products currently listed there, when the caller provides a product-name or keyword query and needs matching products, or when a known product handle must be inspected directly. Product JSON availability alone does not prove that a product ships to a particular destination; destination-specific shipping eligibility may require the site's cart or checkout flow.
Automation Flow
- For a collection, derive the collection handle from the supplied URL or use the supplied handle directly.
- Navigate directly to
https://presenteum.com/collections/{collection-handle}/products.json?limit=50withwaitUntil: "domcontentloaded", then run the collection extractor below in the same browser call. - For keyword lookup, URL-encode
{query}and navigate directly tohttps://presenteum.com/search/suggest.json?q={query}&resources[type]=product,page,article&resources[limit]={limit}withwaitUntil: "domcontentloaded", then run the search extractor below in the same browser call. Use a limit such as10unless the caller requests another value. - When a product handle is already known, navigate directly to
https://presenteum.com/products/{product-handle}.jsonwithwaitUntil: "domcontentloaded", then run the individual-product extractor below. Do not guess a handle; resolve it through predictive search first when only a product name is supplied.
Collection extractor:
(() => {
const data = JSON.parse(document.body.innerText);
return (data.products || []).map(p => {
const variants = Array.isArray(p.variants) ? p.variants : [];
const image = Array.isArray(p.images) && p.images[0] ? p.images[0].src : null;
const body = (p.body_html || '').replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim().slice(0, 160);
return {
href: p.handle ? `/products/${p.handle}` : null,
text: (p.title || '').replace(/\s+/g, ' ').trim().slice(0, 140),
image,
title: p.title || null,
price: variants[0] ? variants[0].price : null,
available: variants.some(v => v.available === true),
productType: p.product_type || null,
body
};
});
})()Search extractor:
(() => {
const data = JSON.parse(document.body.innerText);
const results = data.resources && data.resources.results || {};
return (results.products || []).map(p => ({
title: (p.title || '').replace(/\s+/g, ' ').trim(),
url: p.url || null,
handle: p.handle || null,
price: p.price || (p.variants && p.variants[0] ? p.variants[0].price : null),
image: p.image || (p.featured_image && (p.featured_image.url || p.featured_image)) || null
}));
})()Individual-product extractor:
(() => {
const data = JSON.parse(document.body.innerText);
const p = data.product || {};
const variants = Array.isArray(p.variants) ? p.variants : [];
const body = (p.body_html || '').replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim().slice(0, 220);
return {
handle: p.handle || null,
title: p.title || null,
vendor: p.vendor || null,
productType: p.product_type || null,
price: variants[0] ? variants[0].price : null,
available: variants.some(v => v.available === true),
variants: variants.map(v => ({id: v.id || null, title: v.title || null, price: v.price || null, available: v.available === true})),
body
};
})()Possible Friction Points
- Presentéum exposes collection-scoped Shopify JSON at
/collections/{collection-handle}/products.json?limit=50; use it instead of scraping repeated product cards. - Individual products expose Shopify JSON at
/products/{product-handle}.json; it returns aproductobject with variants, vendor, description, and availability. - Product handles are opaque enough that they must come from supplied input or a search result; never infer one from an arbitrary product name.
- Product JSON availability indicates whether at least one variant is available, not whether the item ships to a requested country. Do not report destination shipping eligibility without evidence from cart, checkout, or an explicit shipping policy.
- Collection responses use
products; product handles are suitable for constructing/products/{handle}URLs. priceis taken from the first variant, whileavailableis true when any variant is marked available.imageis taken from the first product image and isnullwhen no image is present.bodyis plain text derived frombody_html, normalized, and truncated; it may be empty.- Collection endpoints support larger paged reads such as
/collections/all/products.json?limit=250&page={page}. Iterate pages and concatenate results when more than one response is needed; do not assume one response is exhaustive. - Predictive search uses
/search/suggest.jsonwithq={query},resources[type]=product,page,article, andresources[limit]={limit}. Product matches are underresources.results.products; pages and articles are separate. - Search URLs must encode the caller's query. Some responses omit
handle,price, orimage; preserve those fields asnull.