Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.kontext.so/llms.txt

Use this file to discover all available pages before exploring further.

Handling no-fill

Subscribe to ad.no-fill to know when no ad was returned (geo-restriction, frequency cap, server-side skip). The skipCode payload tells you why.
app.use(KontextAdsPlugin, {
  // ...
  onEvent: ({ name, payload }) => {
    if (name === 'ad.no-fill') {
      console.log('No ad available:', payload.skipCode)
    }
  },
})
Every preload produces exactly one of ad.filled / ad.no-fill / ad.error per response, so you can rely on hearing back on every user message.

Pass every message, suppress ads with trackOnly

Always feed every message into the session, even when you don’t want an ad to appear (e.g. user is on a free trial, in a no-ads region, or you’ve decided to show ads only every Nth message). Skipping addMessage calls breaks the conversation context the server relies on for targeting. See Pacing for the full pattern. Use { trackOnly: true } to send the preload for analytics without generating an ad:
const { addMessage } = useAds()
const shouldShowAd = userMessageCount.value % 5 === 0

addMessage(
  { id: msg.id, role: 'user', content: msg.content, createdAt: new Date() },
  { trackOnly: !shouldShowAd }
)
When trackOnly: true, the preload still fires (server keeps full analytics) but no ad.filled event will arrive for that message and no <InlineAd> will render content. The plugin (or <AdsProvider>) reactively passes new props into the underlying session. Bind regulatory to your CMP state and the next preload picks up the new value automatically:
<AdsProvider
  :publisher-token="publisherToken"
  :user-id="userId"
  :conversation-id="conversationId"
  :regulatory="{ gdpr: gdprConsent.applies ? 1 : 0, gdprConsent: gdprConsent.tcString }"
>
  <Chat />
</AdsProvider>
No session recreation needed.

Switching character

The active character cannot be live-updated — the accumulated message history belongs to the original persona, so swapping mid-session would leave messages targeted at the wrong character. To switch character, change the conversationId (and character) prop on <AdsProvider>. The provider tears down the previous session and spins up a new one automatically:
<AdsProvider
  :publisher-token="publisherToken"
  :user-id="userId"
  :conversation-id="conversationId"
  :character="currentCharacter"
>
  <Chat />
</AdsProvider>
The same applies to publisherToken, userId, conversationId, and enabledPlacementCodes — changing any of those rebuilds the session.

Loading older messages (conversation restore)

When restoring a conversation from your backend, call addMessage(...) once per historical message in order. Preloads are debounced (~10 ms), so rapid sequential calls coalesce into a single preload for the most recent user message — you won’t fire one preload per restored message.
const { addMessage } = useAds()

for (const m of loadedFromBackend) {
  addMessage({
    id: m.id,
    role: m.role,
    content: m.content,
    createdAt: m.timestamp,
  })
}