Skip to main content

Recommendations API

Reference for fetching recommendation sections and sending attribution events. For a guided walkthrough, see Loading Recommendations.

useRecommendations()

React hook that fetches recommendation sections for the current page. Must be used within a <GloodProvider> whose client has the recommendations app registered.

Signature

function useRecommendations(
  params: GetSectionsParams,
  options?: UseRecommendationsOptions
): UseRecommendationsResult

Parameters — GetSectionsParams

ParameterTypeRequiredDescription
pageTypePageTypeYesPage the visitor is on: 'home', 'product_page', 'collection', 'cart', 'blog', 'order_confirm', 'checkout', 'ajax_cart', 'returns', '404', 'other'
pageUrlstringNoFull URL of the current page. Defaults to window.location.href in the browser
localestringNoLocale code, e.g. 'en-US'. Defaults to navigator.language in the browser
productIdstring | numberNoNumeric Shopify product id (not GID). Required for product_page recommendations
cartProductIds(string | number)[]NoNumeric product ids currently in the cart
sectionsnumber[]NoSpecific Glood section ids to fetch. Empty = all enabled sections for the page
clientIdstringNoGlood client id. Defaults to the _glood_client_id cookie in the browser
userIdstringNoLogged-in user id
customerIdstringNoShopify customer id
marketstringNoMarket id for multi-market shops
currencystringNoCurrency code
cartValuestringNoCart total value (used for targeting rules)
collectionnumberNoNumeric collection id (for collection pages)
qsstringNoQuery string used for experience assignment
previewbooleanNoInclude disabled sections (preview mode). Default false

Options — UseRecommendationsOptions

OptionTypeRequiredDescription
skipbooleanNoSkip fetching until required params are ready. Default false

Returns — UseRecommendationsResult

AttributeTypeDescription
sectionsRecommendationSection[]Sections with full product data. Empty array while loading or when none configured
dataSectionsResponse | nullFull API response (request_id, experience, visit_id, config, …)
loadingbooleantrue while the request is in flight
errorError | nullGloodApiError on API failures, Error on setup problems
refetch() => voidRe-run the request with the same params
trackRender(track: SectionTrack) => voidSend a glood:section:render attribution event
trackView(track: SectionTrack) => voidSend a glood:section:view attribution event
trackClick(track: SectionTrack) => voidSend a glood:section:click attribution event
trackAddToCart(track: SectionTrack) => voidSend a glood:section:add_to_cart attribution event

Basic Usage

import { useRecommendations } from '@glood/hydrogen';

const { sections, loading, error } = useRecommendations({
  pageType: 'product_page',
  productId: '8977367564515',
});

With All Options

const { sections, data, loading, error, refetch, trackClick } =
  useRecommendations(
    {
      pageType: 'cart',
      cartProductIds: ['8977367564515', '9311227838783'],
      cartValue: '199.00',
      currency: 'USD',
      customerId: '7412356789',
      sections: [218966], // only this section
    },
    { skip: false },
  );

fetchRecommendationSections()

Framework-agnostic fetcher for the sections API. Works server-side (Hydrogen route loaders) and in the browser. The useRecommendations hook uses this internally.

Signature

async function fetchRecommendationSections(
  options: FetchSectionsOptions,
  params: GetSectionsParams
): Promise<SectionsResponse>

Options — FetchSectionsOptions

OptionTypeRequiredDescription
apiKeystringYesGlood storefront token (same value as GloodConfig.apiKey)
myShopifyDomainstringYesShop domain, e.g. 'store-name.myshopify.com'
endpointstringNoEndpoint override. Defaults to https://storefront.glood.ai
debugbooleanNoLog request/response details to the console
The second argument is the same GetSectionsParams as the hook, except pageUrl and locale are required outside the browser (there are no defaults on the server).

Server-Side Usage (Hydrogen Loader)

import { fetchRecommendationSections } from '@glood/hydrogen';

export async function loader({ request, params, context }) {
  const recommendations = await fetchRecommendationSections(
    {
      apiKey: context.env.GLOOD_API_KEY,
      myShopifyDomain: 'your-store.myshopify.com',
    },
    {
      pageType: 'product_page',
      pageUrl: request.url,
      locale: 'en-US',
      productId: params.productId,
    },
  ).catch(() => null);

  return { recommendations };
}

Errors — GloodApiError

Thrown on any non-2xx response:
class GloodApiError extends Error {
  /** HTTP status code, e.g. 401 */
  readonly status: number;

  /** Parsed JSON error body, e.g. { error: 'Invalid authentication' } */
  readonly body: unknown;
}
import { GloodApiError } from '@glood/hydrogen';

try {
  await fetchRecommendationSections(options, params);
} catch (error) {
  if (error instanceof GloodApiError && error.status === 401) {
    // Invalid or mismatched API key
  }
}

RecommendationsApp

The app instance registered via client.use(recommendations()). Retrieve it from the client for advanced usage:
import { RecommendationsApp } from '@glood/hydrogen';

const app = client.getApp('recommendations') as RecommendationsApp;

Methods

MethodReturnsDescription
getSections(params)Promise<SectionsResponse>Fetch sections using the client’s credentials and the app’s endpoint
trackRender(track)voidSend glood:section:render
trackView(track)voidSend glood:section:view
trackClick(track)voidSend glood:section:click
trackAddToCart(track)voidSend glood:section:add_to_cart
sendCustomEvent(name, track)voidGeneric form — send any glood:section:* event by name
const data = await app.getSections({ pageType: 'home' });

app.trackClick({
  section: '218966',
  sectionServeId: data.sections[0].section_serve_id,
  products: [{ productId: '9311227838783' }],
});
Attribution events respect the app’s pixel configuration: if pixel.enabled is false, they are not sent.

SectionTrack Object

Links an attribution event to the exact section render it came from:
AttributeTypeRequiredDescription
sectionstringNoGlood section id (as a string)
sectionServeIdstringRecommendedsection_serve_id from the sections response — ties the event to this specific render
requestIdstringNorequest_id from the sections response
pagestringNoPage type where the interaction happened
parent{ productId?, variantId? }NoContext product (e.g. the product page the section rendered on)
productsSectionTrackProduct[]NoProducts involved: { productId, variantId?, quantity? }
const track: SectionTrack = {
  section: '218966',
  sectionServeId: '56a98d2d-a014-4dd7-ab2d-1a5191b84262',
  requestId: '671778ec-8382-4d9e-9671-fb91daccf049',
  page: 'product_page',
  parent: { productId: '8977367564515' },
  products: [
    { productId: '9311227838783', variantId: '48792371233087', quantity: 1 },
  ],
};

Response Shape — SectionsResponse

interface SectionsResponse {
  /** Unique id for this request — pass to attribution events */
  request_id: string;

  /** Sections with full product data */
  sections: RecommendationSection[];

  /** Current product details (product pages), or null */
  product: Record<string, any> | null;

  /** Shopify storefront access token from the shop config */
  token: string | null;

  /** Shop configuration (currency, money format, integrations, ...) */
  config: Record<string, any>;

  /** Assigned A/B experience id — persisted to localStorage automatically */
  experience: string | null;

  /** Unique id for this visit */
  visit_id: string | null;
}
See TypeScript Types for the full RecommendationSection and SectionProduct definitions.

Example Response

{
  "request_id": "671778ec-8382-4d9e-9671-fb91daccf049",
  "sections": [
    {
      "id": 218966,
      "section_serve_id": "56a98d2d-a014-4dd7-ab2d-1a5191b84262",
      "page_type": "home",
      "experience_id": 27647,
      "layout": "horizontal_grid",
      "location": "MainContent",
      "type": "bestsellers",
      "position": 3,
      "title": "Bestsellers",
      "extra": {},
      "discount_config": { "enabled": false },
      "show_discount_label": false,
      "translations": {},
      "products": [
        {
          "product_id": 9311227838783,
          "title": "The Collection Snowboard: Oxygen",
          "handle": "the-collection-snowboard-oxygen",
          "vendor": "Hydrogen Vendor",
          "product_type": "snowboard",
          "tags": "Premium, Snow",
          "price": 1025,
          "compare_at_price": null,
          "image": { "url": "https://cdn.shopify.com/..." },
          "options": [
            { "id": 1, "name": "Title", "values": ["Default Title"], "position": 1 }
          ],
          "variants": [
            {
              "variant_id": 48792371233087,
              "title": "Default Title",
              "price": 1025,
              "compare_at_price": null,
              "sku": "",
              "selected_options": [{ "name": "Title", "value": "Default Title" }]
            }
          ],
          "metafields": []
        }
      ],
      "cursor": null,
      "hasMore": false
    }
  ],
  "product": null,
  "token": "shpat_...",
  "config": { "shop": { "currency": "USD", "money_format": "${{amount}}" } },
  "experience": "27647",
  "visit_id": "fc300769-ea40-43d9-8bf3-6b721913fea8"
}

See Also