Getting Started
Installation
Section titled “Installation”npm i @elo-ads/web-sdkpnpm add @elo-ads/web-sdkyarn add @elo-ads/web-sdkQuick Start
Section titled “Quick Start”-
Initialize
Create a
EloSDKinstance with your credentials and callinit():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() -
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.adis the matched creative, ornullwhen 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
summarymessage 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
idandcreatedAtyour app keeps for the turn, when it has them, and send the same values on every request; asummarymessage carries the id and time of the turn it summarizes. For a slot with limited height, such as above the composer, passmaxHeightin CSS pixels and the server returns a format that fits. See Ad Formats. -
Show it
Pass
response.adto 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 nullreturn <EloAd sdk={sdk} ad={ad} />}
Full Example
Section titled “Full Example”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> )}Verify Your Integration
Section titled “Verify Your Integration”Open your browser’s Network tab and confirm:
POST /v1/ad/request: sent whenfetchAds()is calledPOST /v1/ad/render: sent when the<EloAd>component mountsPOST /v1/ad/impression: sent after the ad is 50% visible for 1 secondPOST /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.
Requirements
Section titled “Requirements”- React 18 or 19
- A modern bundler (Vite, Next.js, Webpack, etc.)
Next Steps
Section titled “Next Steps”- Rendering Ads: styling, tracking behavior, and best practices
- API Reference: complete SDK types and methods
- Privacy & Consent: GDPR, CCPA, COPPA compliance
- ads.txt: declare Elo as an authorized seller of your inventory