rudra-js

createRudraRecommendationsComponent

import { createRudraRecommendationsComponent } from '@rudra-js/a2ui';

Call createRudraRecommendationsComponent in the browser to add the block to the components an A2UI agent can place.

createRudraRecommendationsComponent(options: RudraRecommendationsOptions) => ReactComponentImplementation

Reference

createRudraRecommendationsComponent(options)

Parameters

  • options: How to load the block, plus every RudraComponent prop except spec, products and bundles. Those props reach the block as they are.
    • loadRecommendations: Fetches the block for one set of hints. The component calls it with request and signal, and renders the result it resolves with.
      • request: The hints the agent set. A blank hint is left out, and so is one your endpoint would turn away, such as a maxItems of 40.
        • currentSkuoptional: The SKU of the product the shopper is looking at or asking about. That product is left out of the block.
        • currentCategoryoptional: The catalog category the shopper is browsing or asking about.
        • searchQueryoptional: What the shopper searched for or asked for, in their own words. The model sees it only with generation: 'per-shopper'.
        • maxItemsoptional: The most products to show, a whole number from 1 to 12.
      • signal: An AbortSignal that fires when the hints change or the component unmounts. Pass it to fetch.
      • result: What to resolve with:
        • spec: The ComponentSpec that generator.generate returned.
        • products: The products the block may show. Send input.candidates from parseTrackingInput, not your raw catalog.
        • bundlesoptional: The sets the block may show. Send input.bundles.
    • placeholderoptional: What to show until the first block arrives. Defaults to nothing.
    • onErroroptional: Called with the error when a load fails, when the result doesn't pass core's schemas, or when the block throws as it renders. The component shows nothing then.
    • registryoptional: Your own renderers, from extendRegistry.
    • hrefForSkuoptional: Returns the link for a product's SKU.
    • formatPriceoptional: Returns the price text for a product.
    • formatBundlePriceoptional: Returns the price text for a set.
    • localeoptional: The language tag prices are formatted for, such as en-US.
    • hasDiagnosticsoptional: Adds attributes that say how the block was built.
    • classNameoptional: A class to add next to rudra.

Returns

A2UI's ReactComponentImplementation for the block. Put it in your browser catalog, next to A2UI's basic components. The agent places it by the name RudraRecommendations.

Caveats

  • Import @rudra-js/a2ui only in code that runs in the browser. On the server the import throws.
  • Give the browser catalog the same id as the agent catalog. A2UI finds it by the catalogId the agent sends.
  • It calls loadRecommendations once the hints have held still for 300 ms. The last block stays up until the next one arrives.
  • Nothing loadRecommendations resolves with reaches the page before it passes core's spec, product and bundle schemas.
  • Each RudraRecommendations on a surface sends its own request.
  • A2UI renders in the browser, so a crawler won't see the block. On a product page, render RudraComponent on the server.

Usage

Adding the block to your browser catalog

Create the component and put it in the catalog your A2UI renderer draws from, next to the basic components.

import type { ReactCatalogComponent } from '@a2ui/react/v0_9';
import { Catalog, MessageProcessor } from '@a2ui/web_core/v0_9';
import { basicCatalog } from '@a2ui/web_core/v0_9/basic_catalog';
import { createRudraRecommendationsComponent } from '@rudra-js/a2ui';

const recommendations = createRudraRecommendationsComponent({
  async loadRecommendations(request, signal) {
    const response = await fetch('/api/recommendations', {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify(request),
      signal,
    });
    if (!response.ok) throw new Error(`recommendations: HTTP ${response.status}`);
    return response.json();
  },
  locale: 'en-US',
});

const shopCatalog = new Catalog<ReactCatalogComponent>(
  'https://shop.example/a2ui/catalog.json',
  'v0.9',
  [...basicCatalog.components.values(), recommendations],
  [...basicCatalog.functions.values()],
);

export const processor = new MessageProcessor<ReactCatalogComponent>([shopCatalog]);

loadRecommendations posts the hints to your endpoint and returns its answer. Throw when the response isn't ok, so the component calls onError.

Render the processor's surfaces with A2uiSurface from @a2ui/react.

Troubleshooting

ReferenceError: HTMLElement is not defined

@a2ui/react needs a DOM, so @rudra-js/a2ui throws this when it loads on the server.

In Next.js a 'use client' file still runs on the server for the first render. Load the file that imports @rudra-js/a2ui from a client component with next/dynamic and ssr: false.