Integrations

Connect Heurix to your platform.

Technical guides with real code, not empty promises. Each integration covers two things: showing Heurix results instead of native search, and keeping your catalog in sync.

Honesty first: these are integration guides meant for a developer, not "one-click install" apps from the Shopify/PrestaShop/etc. stores — that may come if demand justifies it, but we didn't want to claim it before it's true.

Shopify specifics. Shopify doesn't allow running server code with a secret key directly inside a theme (Liquid is server-rendered but can't make authenticated outbound calls). The right architecture: a small serverless function (Cloudflare Worker below, free up to 100,000 requests/day) that holds the real Heurix key and relays requests between your theme and the API — your key is never exposed in the browser.

1. Wiring up search

The relay (Cloudflare Worker):

// worker.js — déployé sur Cloudflare Workers (gratuit pour ce volume)
export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    const q = url.searchParams.get("q") || "";
    const res = await fetch("https://api.heurix.fr/v1/index/" + env.HEURIX_CATALOG + "/search", {
      method: "POST",
      headers: {
        "Authorization": "Bearer " + env.HEURIX_API_KEY,  // secret Cloudflare, jamais exposé
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ q, limit: 20 })
    });
    return new Response(await res.text(), {
      headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": "https://votre-boutique.myshopify.com" }
    });
  }
}

In the theme (Online Store 2.0), replace the rendering of sections/search-results.liquid with a call to this relay:

<div id="heurix-results"></div>
<script>
  const params = new URLSearchParams(window.location.search);
  fetch("https://votre-worker.workers.dev/search?q=" + encodeURIComponent(params.get("q") || ""))
    .then(r => r.json())
    .then(data => {
      document.getElementById("heurix-results").innerHTML = data.hits.map(h =>
        `<a href="/products/${h.product.handle}" class="heurix-hit">
           <span>${h.product.name}</span><span>${h.product.price} €</span>
         </a>`
      ).join("");
    });
</script>

2. Syncing the catalog

Register a Shopify webhook (Admin API or shopify.app.toml for a custom app) on the products/create, products/update, products/delete topics, pointed at the same Worker:

// Ajout dans worker.js : gestion du webhook Shopify
async function handleWebhook(request, env) {
  const product = await request.json();
  await fetch("https://api.heurix.fr/v1/index/" + env.HEURIX_CATALOG + "/items", {
    method: "POST",
    headers: { "Authorization": "Bearer " + env.HEURIX_API_KEY, "Content-Type": "application/json" },
    body: JSON.stringify({
      rulepack: "mode",
      items: [{
        id: String(product.id),
        name: product.title,
        ref: product.variants?.[0]?.sku || "",
        description: product.body_html?.replace(/<[^>]+>/g, "") || "",
        stock: product.variants?.reduce((s, v) => s + (v.inventory_quantity || 0), 0) || 0,
        handle: product.handle,
        price: product.variants?.[0]?.price
      }]
    })
  });
}

Remember to verify the Shopify webhook's HMAC signature (X-Shopify-Hmac-Sha256) before processing the payload, to avoid accepting forged requests.

A question about your platform?

These guides are a technical starting point, not a turnkey module. If your setup is out of the ordinary, get in touch.

14-day free trial

Try the Search API on your catalog, no credit card.

See pricing