Skip to content

Getting Started

Terminal window
npm i @elo-ads/web-sdk
  1. Initialize

    Create a EloSDK instance with your credentials and call init():

    import { EloSDK } from '@elo-ads/web-sdk'
    const sdk = new EloSDK({
    publisherId: 'YOUR_PUBLISHER_ID',
    adUnitId: 'YOUR_AD_UNIT_ID',
    backendUrl: 'https://api.withgrowl.com',
    })
    await sdk.init()
  2. Load an ad

    Pass the current chat messages to fetchAds(). It’s important that you send all the chat messages of the current chat for relevant ads:

    const response = await sdk.fetchAds({
    messages: [
    { role: 'user', content: 'What noise-cancelling headphones do you recommend?' },
    { role: 'assistant', content: 'Here are some great options for noise-cancelling headphones...' },
    ],
    })

    response.ad is the matched creative, or null when there’s no fill — always handle both.

    For long conversations where sending the entire history is impractical, or if you’d like to limit how much you share, send a summary message followed by the most recent user/assistant exchange instead:

    const response = await sdk.fetchAds({
    messages: [
    { role: 'summary', content: 'User is shopping for noise-cancelling headphones under $300, mostly for flights.' },
    { role: 'user', content: 'What about battery life?' },
    { role: 'assistant', content: 'Most flagship models get 30+ hours...' },
    ],
    })

    Either shape works — pick whichever fits your app’s chat-history model.

    Give each message the id and createdAt your app keeps for the turn, when it has them, and send the same values on every request; a summary message carries the id and time of the turn it summarizes. For a slot with limited height, such as above the composer, pass maxHeight in CSS pixels and the server returns a format that fits. See Ad Formats.

  3. Show it

    Pass response.ad to the <EloAd> React component to display the ad in the format the server chose. It handles render and impression tracking automatically.

    import { EloAd } from '@elo-ads/web-sdk'
    function ChatAdSlot({ sdk, ad }) {
    if (!ad) return null
    return <EloAd sdk={sdk} ad={ad} />
    }
App.tsx
import { EloSDK, EloAd } from '@elo-ads/web-sdk'
import type { AdCreative } from '@elo-ads/web-sdk'
import { useEffect, useState } from 'react'
const sdk = new EloSDK({
publisherId: 'YOUR_PUBLISHER_ID',
adUnitId: 'YOUR_AD_UNIT_ID',
backendUrl: 'https://api.withgrowl.com',
})
function Chat() {
const [ad, setAd] = useState<AdCreative | null>(null)
const [ready, setReady] = useState(false)
useEffect(() => {
sdk.init().then(() => setReady(true))
}, [])
async function onAssistantMessage(messages) {
if (!ready) return
const response = await sdk.fetchAds({ messages })
setAd(response.ad)
}
return (
<div>
{/* your chat UI */}
{ad && <EloAd sdk={sdk} ad={ad} />}
</div>
)
}

Open your browser’s Network tab and confirm:

  1. POST /v1/ad/request: sent when fetchAds() is called
  2. POST /v1/ad/render: sent when the <EloAd> component mounts
  3. POST /v1/ad/impression: sent after the ad is 50% visible for 1 second
  4. POST /v1/sdk/events: sent when the card is clicked, recording where inside it the click landed

The click itself doesn’t appear here. It’s a navigation to the ad server’s tokenized click_url in a new tab, which the ad server counts at that URL.

  • React 18 or 19
  • A modern bundler (Vite, Next.js, Webpack, etc.)