# Варианты интеграций

Готовые сценарии для типовых задач. Все примеры предполагают, что `wrapper.js` уже подключён:

```html
<script async src="https://mads-media.magnit.ru/web-sdk/current/wrapper.js"></script>
```

---

## Несколько плееров на одной странице

SDK не имеет внутреннего ограничения на количество плееров. Каждый вызов `MadsPlayer(...)` создаёт независимый экземпляр с собственным iframe.

```html
<div id="ad-top"></div>
<div id="ad-sidebar"></div>
<div id="ad-bottom"></div>

<script>
    window.MadsPlayer({ container: '#ad-top',     padId: 100 });
    window.MadsPlayer({ container: '#ad-sidebar', padId: 101 });
    window.MadsPlayer({ container: '#ad-bottom',  padId: 102 });
</script>
```

Каждый плеер сам отслеживает свою видимость и фокус — если на экране только верхний контейнер, остальные не будут расходовать сеть.

---

## Ленивая загрузка при скролле

Не создавайте `MadsPlayer` сразу — дождитесь, пока контейнер появится в viewport.

```html
<div id="ad-lazy" style="min-height: 250px;"></div>

<script>
    const target = document.getElementById('ad-lazy');
    let player = null;

    const io = new IntersectionObserver((entries) => {
        if (entries[0].isIntersecting && !player) {
            player = window.MadsPlayer({
                container: target,
                padId: 193,
            });
            io.disconnect();
        }
    }, { rootMargin: '200px' });

    io.observe(target);
</script>
```

`min-height` на контейнере резервирует место и предотвращает layout shift до подгрузки креатива.

---

## Перезапуск с другим `padId`

SDK не умеет менять `padId` «на лету» — нужно уничтожить старый плеер и создать новый.

```js
let player = window.MadsPlayer({ container: '#ad', padId: 100 });

async function reload(newPadId) {
    await player.destroy();
    player = window.MadsPlayer({ container: '#ad', padId: newPadId });
}

document.getElementById('btn-other-ad').onclick = () => reload(200);
```

`destroy()` возвращает Promise — дождитесь его перед созданием нового плеера, чтобы fade-анимация успела отыграть.

---

## SPA: React / Vue / Svelte

Базовый принцип: создавайте плеер в момент монтирования компонента, уничтожайте при размонтировании.

### React (хук)

```jsx
import { useEffect, useRef } from 'react';

export function MadsAd({ padId }) {
    const containerRef = useRef(null);

    useEffect(() => {
        if (!window.MadsPlayer || !containerRef.current) return;

        const player = window.MadsPlayer({
            container: containerRef.current,
            padId,
            onError: (e) => console.error('MADS error', e),
        });

        return () => {
            player?.destroy();
        };
    }, [padId]);

    return <div ref={containerRef} style=250 />;
}
```

При смене `padId` хук уничтожит старый плеер и создаст новый.

### Vue 3 (Composition API)

```vue
<template>
    <div ref="container" style="min-height: 250px;"></div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';

const props = defineProps({ padId: Number });
const container = ref(null);
let player = null;

onMounted(() => {
    player = window.MadsPlayer({
        container: container.value,
        padId: props.padId,
    });
});

onBeforeUnmount(async () => {
    await player?.destroy();
});
</script>
```

### Svelte

```svelte
<script>
    import { onMount, onDestroy } from 'svelte';

    export let padId;
    let container;
    let player;

    onMount(() => {
        player = window.MadsPlayer({ container, padId });
    });

    onDestroy(() => {
        player?.destroy();
    });
</script>

<div bind:this={container} style="min-height: 250px;"></div>
```

---

## Ожидание загрузки `wrapper.js`

При `<script async>` тег `wrapper.js` загружается параллельно с парсингом страницы и `window.MadsPlayer` может быть ещё не определён в момент вашего инициализационного кода. Безопасные подходы:

### Вариант 1: дождаться `load` события

```js
window.addEventListener('load', () => {
    window.MadsPlayer({ container: '#ad', padId: 193 });
});
```

### Вариант 2: очередь через `sdkInit`

SDK поддерживает массив `window.sdkInit` — конфиги из него будут проиграны автоматически после загрузки `wrapper.js`. Удобно, если вы инлайните инициализационный скрипт до `wrapper.js`:

```html
<script>
    window.sdkInit = window.sdkInit || [];
    window.sdkInit.push([{ container: '#ad', padId: 193 }]);
</script>
<script async src="https://mads-media.magnit.ru/web-sdk/current/wrapper.js"></script>
```

---

## Подстановка своих параметров в пиксели

Если ваши креативы используют плейсхолдеры в URL пикселей (например, `[user_id]`), передайте значения через `macro`:

```js
window.MadsPlayer({
    container: '#ad',
    padId: 193,
    macro: {
        user_id: getCurrentUserId(),
        session_id: getSessionId(),
        ab_variant: 'B',
    },
});
```

SDK заменит все вхождения `[user_id]`, `[session_id]`, `[ab_variant]` в URL пикселей на значения из `macro` (URL-encoded). Подробнее — в разделе [События и трекинг](events-and-tracking.md).

`userId` в конфиге — другое поле: оно уходит в запрос ad-сервера для персонализации, а не в URL пикселей.

---

## Программное управление через SDK mode

Когда нужны кастомные кнопки play/pause/skip:

```html
<button id="play">▶</button>
<button id="pause">⏸</button>
<button id="skip">⏭</button>
<div id="ad"></div>

<script>
    window.addEventListener('load', () => {
        const player = window.MadsPlayer({
            mode: 'sdk',
            container: '#ad',
            padId: 193,
        });

        document.getElementById('play').onclick  = () => player.play();
        document.getElementById('pause').onclick = () => player.pause();
        document.getElementById('skip').onclick  = () => player.skip();
    });
</script>
```

В `sdk` режиме плеер скрыт до первого `play()`. Команды можно вызывать сразу — SDK буферизует их до готовности iframe. Подробнее — в [Быстром старте](publishers.md#6-sdk-mode--программное-управление).

---

## Модальное окно на сайте

Для `modalwindow` контейнер всё равно обязателен — SDK монтируется в него, — но само окно рисуется overlay поверх страницы и не занимает место в потоке.

```html
<div id="ad-modal"></div>

<script>
    window.addEventListener('load', () => {
        window.MadsPlayer({
            container: '#ad-modal',
            padId: 253,
            userId: getCurrentUserId(),
            onSkipped: () => console.log('модалка закрыта'),
            onError: (e) => console.warn(e.code, e.message),
        });
    });
</script>
```

- Не задавайте контейнеру `min-height` «под креатив» — останется пустая полоса: окно живёт над страницей.
- Пока модалка открыта, страница не скроллится; после закрытия скролл возвращается.
- Не вешайте на предков контейнера `transform` / `filter` / `perspective`, если можно этого избежать. SDK умеет перенести iframe к `body`, но проще не создавать containing block.
- Закрытие — крестик или Escape (`onSkipped`). `onCompleted` у этого формата нет.

Подробнее — [Форматы](formats.md#modalwindow) и [Размеры и адаптив](sizing.md#модалка-modalwindow).

---

## A/B тесты с переключением `padId`

Используйте URL-параметр `?pad_id=...` — он перекрывает значение из конфига. Удобно для тестирования без редеплоя:

```
https://your-site.com/page?pad_id=999
```

В коде оставьте «дефолтный» padId, а тестировщики смогут открывать страницу с любым другим:

```js
window.MadsPlayer({ container: '#ad', padId: 193 });
// Если открыть страницу с ?pad_id=999 — SDK возьмёт 999 вместо 193
```
