npm package: @schibsted/niche-ads
Description: Package containing ads logic reappearing across our projects
Latest version: 5.5.4
Deprecated: Package is no longer maintained

# Niche ads

This package is no longer maintained, please switch to [Advertory](https://github.schibsted.io/inventory/advertory) package (`@sch-inventory/advertory`). You may also find our Advertory adapter useful (`@schibsted/niche-advertory-adapter`).

## Description

This repository contains code we use for appnexus ads. Given the right config it can request and return ready to display appnexus ads. It is possible to pass configuration for ads different than appnexus but in that case you will get back your config. It was added to enable using this libary for mixed appnexus and different ads. **If you don't use appnexus ads then this library is not for you!**

## Local development

First install dependencies
clone repository, open terminal and run.

```bash
npm ci
```

Next start transpiling the source code:

```bash
npm run dev
```

### Linking

Note: order of command execution is important.

In order to make your project available as package locally:

```bash
npm link
```

And in project you need:

```bash
npm link @schibsted/niche-ads
```

Since library has `react` as peer dependency you need to make sure to pass `react` manually to the library if you want to use linked version. The easiest way to do so is to declare `react` as a webpack alias, e.g.

```js
config.resolve.alias.react = path.resolve('./node_modules/react');
```

If the project you use this package in, does not have webpack, you can try https://benjaminwfox.com/blog/tech/why-isnt-npm-link-working#if-you-use-react.

And now you are all good. Your project will now use the local version of niche-ads instead of the one in node_modules.

### Unlinking

After you end working on the package you need to unlink it.

First, in the project where the package was used:

```bash
npm unlink --no-save @schibsted/niche-ads
```

Second, in the niche-ads package:

```bash
npm unlink
```

## How to use it and how it works

Package exports 4 entities `AdContext`, `AdContextProvider`, `usePlacement`, `useLoadAds`.

### AdContext

Ideally you won't ever need to use this directly. It may be usefull for debugging or to peek what the library is storing under the hood. Ideally you should use `AdContextProvider`. One thing you may find useful there is `adBlockerDetectedPromise` that is a promise that resolves to a boolean and states whether we suspect that adblock was used (we weren't able to load ad script).

### AdContextProvider

Ideally you should wrap your application with `AdContextProvider` quite close to the start of your application.

Minimal usage example:

```js
import { AdContextProvider } from '@schibsted/niche-ads';

function SomeComponent({ children, adsConfig, device }) {
    return (
        <AdContextProvider adsConfig={publicRuntimeConfig.ads} device={device}>
            {children}
        </AdContextProvider>
    );
}

export default SomeComponent;
```

#### Configuration

-   **device** - required - string - one of `desktop`, `tablet`, `mobile`
-   **adsConfig** - required - object - ads configuration object
    -   **options** - required - object
        -   **member** - number - required - member client id
        -   other options to pass to appnexus, for example `disablePsa` or `enableSafeFrame`
    -   **keywords** - optional - object - keywords to pass to different placements, see example
    -   **placements** - required - object - placements to render, see example
-   **cdn** - optional - string - defaults to `https://acdn.adnxs.com/ast/ast.js`
-   **children** - required - react node - react children to render
-   **cogwheelCdn** - optional - string - defaults to `https://cogwheel.inventory.schibsted.io/prod/latest/gdpr-bundle.js`
-   **wallpaper** - optional - object - configuration for wallpaper ad
    -   **enabled** - required - boolean - defaults to `false`
    -   **setWallpaperFunction** - required (if enabled is true) - function - callback to set image as a page background, you will get url as a parameter
    -   **setBackgroundColorFunction** - required (if enabled is true) - callback to set color as a page background, you will get color as a parameter
    -   **enabled** - required - boolean - defaults to `false`
-   **glimr**
    -   **enabled** - required - boolean - defaults to `false`
    -   **shouldLoad** - required - funciton - async function returning boolean, this is used to opt out for example by checking privacy permissions
    -   **clientId** - optional - string - glimr client id
    -   **localStorageKey** - optional - string - defaults to `glimrTags`
    -   **localStorageExpiration** - optional - number - defaults to `24 * 60 * 60 * 1000` (24h)
-   **eids** - optional - object - config for eids
    -   **required** - required - boolean - defaults to `false`, waits with ad request until eids are given
    -   **region** - required - string - defaults to `SCHNO` - region of the user, either `SCHNO` or `SCHSE`

##### Example adsConfig

```js
{
    options: {
        member: 9700, // 9700 - regular member, 9826 - test seat
        disablePsa: true,
        enableSafeFrame: true,
    },
    placements: {
        common: {
            noBidIfUnsold: true, // will be passed to all placements
        },
        desktop: {
            other: [ // different type of pages, usually article, front and other are used
                {
                    targetId: 'advert-topboard',
                    invCode: 'no-pent-wde-other_topboard',
                    sizes: [
                        [1010, 300],
                        [1010, 150],
                        [980, 300],
                        [980, 150],
                        [1000, 150],
                    ],
                    alwaysUseXDomainIframe: true,
                    keywords: {
                        'no-sno-adformat': 'topboard',
                    },
                },
            ],
        },
        tablet: {
            other: [
                {
                    targetId: 'advert-topboard',
                    invCode: 'no-pent-wtb-other_topboard',
                    sizes: [
                        [980, 300],
                        [980, 250],
                        [768, 250],
                    ],
                    keywords: {
                        'no-sno-adformat': 'topboard',
                    },
                },
            ],
        },
        mobile: {
            other: [
                {
                    targetId: 'advert-board_1',
                    invCode: 'no-pent-wph-front_board_1',
                    sizes: [
                        [320, 250],
                        [300, 250],
                        [320, 400],
                    ],
                    keywords: {
                        'no-sno-adformat': 'board_1',
                    },
                },
            ],
        },
    },
    keywords: {
        common: {
            'aa-sch-country_code': 'no',
            'aa-sch-publisher': 'pent',
            'no-sno-publishergroup': 'schibsted',
            'aa-sch-inventory_type': 'other',
            'aa-sch-page_type': 'other',
        },
        desktop: {
            common: {
                'aa-sch-supply_type': 'web_desktop',
            },
        },
        tablet: {
            common: {
                'aa-sch-supply_type': 'web_tablet',
            },
        },
        mobile: {
            common: {
                'aa-sch-supply_type': 'web_phone',
            },
        },
    },
}
```

##### Example `setWallpaperFunction`

```js
const setWallpaper = (url) => {
    document.body.style.backgroundImage = `url(${url})`;
    document.body.style.backgroundRepeat = 'no-repeat';
    document.body.style.backgroundAttachment = 'fixed';
};
```

##### Example `setBackgroundColour`

```js
export const setBackgroundColour = (colour) => {
    document.body.style.backgroundColor = colour;
};
```

## How to pass pulse ads identifiers

Xandr now accepts pulse identifiers, to set them you will have to call `ppids` event on `adsEventTarget` with `{PPID1, PPID2}` object in details. You can do it like this:

```js
const [PPID1, PPID2] = await Promise.all([pulseInstance.getXandrPPID1(), pulseInstance.getXandrPPID2()]);

adsEventTarget.dispatchEvent(new CustomEvent('ppids', { detail: { PPID1, PPID2 } }));
```

To check if they are working you can look for `eids` property in request for ads.