Connect the block to the AEM Edge Function

IMPORTANT
AEM Edge Functions is currently in beta. Features and documentation may change. For feedback, contact aemcs-edgecompute-feedback@adobe.com.

Our goal is to build a dynamic Edge Delivery Services block that calls an AEM Edge Function to fetch dynamic data from a third-party API.

The third step is to connect the Edge Delivery Services block you scaffolded in Develop the Edge Delivery Services block to the AEM Edge Function you built in Develop the AEM Edge Function. This is the step that ties the two projects together. Run both local dev servers side by side, at two different ports, and make the block’s JavaScript call the right one depending on where it’s running.

Run both local dev servers

In the Edge Delivery Services site project:

$ aem up

This serves the site at http://localhost:3000.

In the AEM Edge Functions project, in a second terminal:

$ aio aem edge-functions serve

This serves the endpoint at http://127.0.0.1:7676.

Wire up the fetch call

Add the following to estimated-delivery.js, alongside the scaffold from Develop the Edge Delivery Services block.

Pick the right URL for the environment

The Edge Delivery Services block calls a different URL depending on where it’s running:

Environment
URL the block calls
Why
Local dev
http://127.0.0.1:7676/api/frescopa/estimated-delivery
The Edge Delivery Services block and the AEM Edge Function are two separate local servers on two different ports
Deployed
/api/frescopa/estimated-delivery (relative)
The CDN origin selector routes this path to the AEM Edge Function on the site’s own domain

Detect local dev from the hostname the browser reports, and cache the result so every request doesn’t repeat the check:

// blocks/estimated-delivery/estimated-delivery.js
const API_PATH = '/api/frescopa/estimated-delivery';
const LOCAL_EDGE_FUNCTION_ORIGIN = 'http://127.0.0.1:7676';

let cachedApiUrl;

function isLocalDev() {
  const { hostname } = window.location;
  return hostname === 'localhost' || hostname === '127.0.0.1';
}

function getEstimatedDeliveryApiUrl() {
  if (cachedApiUrl) return cachedApiUrl;

  // Local: site (aem up) on :3000, Edge Function on :7676 — call it directly.
  // Production: relative path, routed to Edge Function via CDN origin selector.
  cachedApiUrl = isLocalDev()
    ? `${LOCAL_EDGE_FUNCTION_ORIGIN}${API_PATH}`
    : API_PATH;

  return cachedApiUrl;
}

This is the only environment-specific logic in the Edge Delivery Services block. Everything else, the fetch call, the response handling, the rendering, works the same in both environments because the path is the same; only the origin changes.

NOTE
The local dev call crosses origins (localhost:3000 to 127.0.0.1:7676), so it depends on the CORS headers you added to the AEM Edge Function in Develop the AEM Edge Function. Without them, the browser blocks the response and the fetch call throws a generic network error.

Call the AEM Edge Function

// blocks/estimated-delivery/estimated-delivery.js
async function fetchEstimatedDelivery(sku, postcode, signal) {
  const params = new URLSearchParams({ sku, postcode });
  const response = await fetch(`${getEstimatedDeliveryApiUrl()}?${params.toString()}`, {
    signal,
    cache: 'no-store',
  });

  const body = await response.json().catch(() => ({}));

  if (!response.ok) {
    const apiMessage = body.message || body.error;
    const err = new Error(apiMessage || 'Unable to check estimated delivery right now.');
    err.code = body.code;
    throw err;
  }

  return body;
}

err.code carries the same code field from Define the API contract (MISSING_POSTCODE, UNKNOWN_SKU), so a caller could branch on it. The Edge Delivery Services block only displays message. cache: 'no-store' keeps the browser from caching a personalized response. The CDN’s own cache behavior is controlled separately, by skipCache in cdn.yaml, covered in Build an API endpoint.

Wire up the submit handler

Add this inside decorate(), after the form markup from Develop the Edge Delivery Services block. This is the core pattern: cancel any in-flight request, show loading, call the function, and route the outcome to setState:

// blocks/estimated-delivery/estimated-delivery.js
form.addEventListener('submit', async (event) => {
  event.preventDefault();
  // ...extract and validate sku/postcode from the form, omitted here...

  activeRequest?.abort();
  const controller = new AbortController();
  activeRequest = controller;

  setState({ loading: true });

  try {
    const data = await fetchEstimatedDelivery(sku, postcode, controller.signal);
    setState({ data });
  } catch (err) {
    if (err.name === 'AbortError') return;
    setState({ error: formatError(err) });
  }
});

setState wraps renderResult(), which switches between the loading, error, and success markup. A thrown error routes through formatError(), which distinguishes a network failure (the AEM Edge Function isn’t reachable, so the local dev server isn’t running or the CDN route isn’t deployed yet) from a business error the AEM Edge Function returned on purpose, for example an unknown SKU. The full handler also validates the postcode client-side before calling the function at all, and disables the submit button while a request is in flight. See the complete listener, renderResult(), and formatError() in estimated-delivery.js.

Test the full loop locally

With both dev servers running, open the page you authored at http://localhost:3000/dev/branches/estimated-delivery, submit the form, and confirm the result renders as a status-colored card with data from the AEM Edge Function’s upstream calls.

Estimated delivery success card rendered locally with live data

Then verify the other two states:

  • Submit with the postcode field empty. The Edge Delivery Services block should show “Postcode required” without making a network call, confirming the client-side check runs before fetchEstimatedDelivery().

  • Stop aio aem edge-functions serve and submit again. The Edge Delivery Services block should show the local network-failure hint, confirming formatError() picked the local-dev branch.

    Estimated delivery network-failure hint after stopping the local Edge Function

Open the browser console for any of these. If a request fails unexpectedly, check first whether it’s a CORS error (fix in the AEM Edge Function) or a connection error (the AEM Edge Function’s dev server isn’t running).

Next steps

In Deploy and verify, you deploy both projects and confirm the same flow works against your Dev site, not just locally.

Additional resources

recommendation-more-help
experience-manager-learn-help-cloud-service