Developer FAQ

Developer FAQ #

This section addresses the most common questions developers ask when integrating Monetag ads into their Telegram Mini Apps. All answers are based on real-world usage, support cases, and internal best practices.

What zone ID should I use in the SDK? #

Always use the main zone ID provided by Monetag.
Each SDK setup includes one main zone and several linked sub-zones — only the main zone should be used in:

  • The <script> tag (data-zone="XXX")
  • The npm SDK call (createAdHandler(XXX))

Using a sub-zone ID will cause the SDK to work incorrectly or not at all.

What is ymid and do I need it? #

ymid is an optional identifier that you can pass when calling show_XXX() to help you match postbacks with user actions on your backend.

You can use:

  • User ID
  • Session ID
  • UUID
  • Any string that helps link the action to your system

If ymid is not provided, {ymid} in the postback is empty. The SDK does not use the Telegram user ID as ymid. When the Telegram WebApp API is initialized, the SDK sends the Telegram user ID separately, and it arrives in the postback as {telegram_id}.

What’s the difference between requestVar and ymid? #

  • ymid identifies a user or event on your backend. It arrives in the postback as {ymid}.
  • requestVar identifies a placement, for example a button. It arrives in the postback as {request_var} and is also visible in Monetag statistics. For Rewarded Popup the postback value is <main zone ID>_<requestVar>.

Use requestVar if you want to distinguish different placements (e.g. different buttons).

Can I preload ads before showing them? #

Yes. Preloading is highly recommended for Rewarded Interstitials and In-App Interstitials.

show_XXX({ type: 'preload', ymid: 'session-123' }).then(() => {
  show_XXX({ ymid: 'session-123' })
})

This reduces latency and improves UX.

Can I use multiple ad formats at once? #

Yes, the SDK supports Rewarded Interstitial, Rewarded Popup, and In-App Interstitial — and you can use them together in one app.
However, we recommend avoiding too many ads in short time spans.

Why isn’t the ad appearing? #

Check the following:

  • Are you using the correct (main) zone ID?
  • Is the SDK script actually loaded before calling the function?
  • Are you calling the ad method from a user interaction (especially for popups)?
  • Is .catch() implemented for error handling?
  • Is there ad inventory available at that moment?

Do I need to wait for the SDK to be ready before calling it? #

Yes. Make sure the SDK script is loaded. In React or modern frameworks, call it from useEffect or after DOM is ready.

Can I use the SDK with Next.js / React? #

Yes. Use the npm package monetag-tg-sdk and call createAdHandler(zoneId) once, then use the returned function where needed.

Example:

import createAdHandler from 'monetag-tg-sdk'

const adHandler = createAdHandler(YOUR_ZONE_ID)

const onClick = () => {
  adHandler({ ymid: 'user-123' }).then(() => {
    // success logic
  }).catch(() => {
    // fallback
  })
}

What if the ad fails to load or show? #

Always use .catch() to detect failure and show fallback logic (another ad, retry, or notification).

Example:

show_XXX().catch(() => {
  showOtherAd()
})

Can I show an ad during page transitions? #

Yes. The SDK allows you to show Rewarded Interstitial ads at any time, including during navigation between pages or views.

You can call show_XXX() whenever needed — including in routing hooks or page transition events. This makes it possible to implement interstitial ads between screens, similar to how ads work in native mobile apps.

React + React Router Example #

If you’re using react-router-dom, you can hook into route changes like this:

import { useEffect } from 'react'
import { useLocation } from 'react-router-dom'

const AdOnRouteChange = () => {
  const location = useLocation()

  useEffect(() => {
    show_XXX({
      ymid: getUUID(),
      requestVar: 'router_change'
    })
  }, [location])

  return null
}

Make sure this component is mounted outside your main routing switch, so it doesn’t unmount during transitions.

Replace XXX with your actual zone ID.

How can I handle timeouts or blocked ad resources? #

Sometimes an ad may fail to load or show due to network issues, blocked domains (e.g., country-level firewalls), etc. To handle such cases, we recommend using preload with timeout and showing fallback content if needed.

You can preload the ad in the background and show it later if it was successfully loaded.
Use the type: 'preload' option together with timeout (in seconds) to limit how long the SDK will wait for the preload operation.

let preloaded = false;

show_XXX({ type: 'preload', timeout: 5, ymid: 'user123' })
  .then(() => {
    preloaded = true;
  })
  .catch(() => {
    // preload failed — ad not available
  });

button.onclick = () => {
  if (preloaded) {
    show_XXX({ ymid: 'user123' });
  } else {
    alert('No ads available, try again later.');
  }
};

React Example:

const [isPreloaded, setIsPreloaded] = React.useState(false);

React.useEffect(() => {
  show_XXX({ type: 'preload', timeout: 5, ymid: 'user123' })
    .then(() => setIsPreloaded(true))
    .catch(() => setIsPreloaded(false));
}, []);

const onClick = () => {
  if (!isPreloaded) {
    return alert('No ads available, try again later.');
  }

  show_XXX({ ymid: 'user123' });
  setIsPreloaded(false);
};

return <button onClick={onClick}>Show ad</button>;

This pattern gives users faster feedback and avoids UI freezes caused by slow or blocked ad requests.

timeout for direct calls #

timeout (in seconds) works for type: 'preload', type: 'start' and type: 'end' (the default). For 'end', the SDK preloads the ad with this timeout, then shows it. If the preload is not ready in time, the Promise rejects with Timeout. The time the ad is on screen is not limited. timeout has no effect for 'pop' and 'inApp'.

If you need to handle fallback logic when an ad fails to show, use .catch():

show_XXX({ ymid: 'user123' })
  .then(() => {
    // ad was shown and closed
  })
  .catch(() => {
    // ad failed — show fallback
  });

🟢 Summary:

  • Use type: 'preload' + timeout to control background loading
  • Always pair with .catch() to handle errors or fallback paths

This FAQ will expand as we collect more developer feedback. If your question isn’t listed here, reach out to Monetag support or your account manager.