niche-advertory-adapter
Library that bridges the gap between @sch-inventory/advertory
and Niche projects working on Next.js. @sch-inventory/advertory
is published only on Artifactory.
Link to Advertory
By design this library is not directly using @sch-inventory/advertory
so that for most cases you will have do to changes in at most 2 projects from:
@schibsted/niche-advertory-adapter
@sch-inventory/advertory
- web frontent you are working on
API of this library is largely compatible with @schibsted/niche-ads
library to simplify the switch.
Usage
Creating instance
import { initAdvertoryPackage } from '@sch-inventory/advertory/core/minmote';
import { Device } from '@schibsted/niche-advertory-adapter';
import type { invCodeBuilderSignature } from '@schibsted/niche-advertory-adapter';
import { AdvertoryAdapter } from '@schibsted/niche-advertory-adapter';
import { adsConfig } from '@constants/ads';
const mapDevice = (device: Device) => {
switch (device) {
case Device.Desktop:
return 'wde';
case Device.Mobile:
return 'wph';
case Device.Tablet:
return 'wtb';
default:
throw new Error('Unknown device');
}
};
const nicheInvCodeBuilder: invCodeBuilderSignature = (placement, device, pageType) =>
`no-minmote-${mapDevice(device)}-${pageType}_${
Array.isArray(placement.adFormat) ? placement.adFormat[0] : placement.adFormat
}`;
export const ads = new AdvertoryAdapter({
advertoryConfig: {
country: 'no',
defaultThreshold: 200,
fullscreenScroll: {
...
},
prebid: {
...
},
publisher: 'minmote',
tcf: {
enabled: false,
},
},
glimr: {
clientId: 'H3IYO2A4LD43YPFZIJLN',
},
initAdvertoryPackage,
nicheAdsConfig: adsConfig,
nicheInvCodeBuilder,
});
Configuration
advertoryConfig
- configuration passed to advertory's initAdvertoryPackage
function, check advertory documentation for more detailsfinnBlink
- optional configuration for finn blink ad, should be object with channel
propertyglimr
- configuration for glimr, only required parameter is clientId
(it's disabled by default, at this point of initialization we don't know if we can use glimr due to user consents)initAdvertoryPackage
- function that initializes advertory package, it's different for each project (different import from advertory package)nicheAdsConfig
-
keywords
- keyboards to be set on the whole ad callpageOptions
- passed to advertory, look there for documentationplacements
- placement configuration, not advertory format, our is much shorter
nicheInvCodeBuilder
- function building invCode based on placement config, device and pageType, example implementation is provided above
nicheAdsConfig
example:
{
keywords: {
common: {
'no-sno-publishergroup': 'schibsted',
},
desktop: {
article: {
'aa-sch-page_type': 'article',
},
common: {
'aa-sch-supply_type': 'web_desktop',
},
front: {
'aa-sch-page_type': 'front',
},
other: {
'aa-sch-page_type': 'other',
},
},
mobile: {
article: {
'aa-sch-page_type': 'article',
},
common: {
'aa-sch-supply_type': 'web_phone',
},
front: {
'aa-sch-page_type': 'front',
},
other: {
'aa-sch-page_type': 'other',
},
},
tablet: {
article: {
'aa-sch-page_type': 'article',
},
common: {
'aa-sch-supply_type': 'web_tablet',
},
front: {
'aa-sch-page_type': 'front',
},
other: {
'aa-sch-page_type': 'other',
},
},
}
pageOptions: {
member: 9700,
disablePsa: true,
enableSafeFrame: true,
},
placements: {
common: {
allowedFormats: ['banner', 'video', 'native'],
native: {
desc2: { required: false },
icon: { required: false, sizes: [{}] },
image: { required: false, sizes: [{}] },
sponsoredBy: { required: false },
title: { required: false },
video: { min_duration: 0, required: false },
},
noBidIfUnsold: true,
},
desktop: {
article: [
{
adFormat: 'netboard_1',
sizes: [...netboardSizes, nativeSize],
targetId: 'text_ad_1',
},
],
front: [
{
adFormat: ['brandboard_1', 'fullscreen'],
sizes: [...brandboardSizes, takeoverSize],
targetId: 'front_ad_1',
},
],
},
mobile: {
article: [
{
adFormat: 'board_1',
sizes: [...boardSizes, nativeSize],
targetId: 'text_ad_1',
},
],
front: [
{
adFormat: ['board_1', 'board_fullscreen'],
sizes: [...boardSizes, takeoverSize, nativeSize],
targetId: 'front_ad_1',
},
],
},
get tablet() {
return adsConfig.placements.desktop;
},
}
If you want to add finn blink to a placement you need to add finnBlink
object to placement config, e.g.:
{
adFormat: 'board_1',
sizes: [...boardSizes, nativeSize],
targetId: 'text_ad_1',
finnBlink: {
enabled: true,
position: 'hayabusa_text_ad_1',
},
}
Initalization
Before you initialize ads you need to know if you can use glimr and have pulse instance.
Initialize adapter:
function adsInitialization(pulseInstance) {
return ads.initialize({
glimr: {
enabled: findGlimrPermissions(),
},
pulseInstance,
});
}
If you want finn blink ads it should look like this:
async function adsInitialization(pulseInstance, user) {
const hasGlimrPermissions = await findGlimrPermissions();
return ads.initialize({
finnBlink: {
enabled: Boolean(hasBlinkAdPermission() && user?.userId && user?.uuid),
userId: user?.userId,
uuid: user?.uuid,
},
glimr: {
enabled: hasGlimrPermissions,
},
pulseInstance,
});
}
Where hasBlinkAdPermission
looks like this:
const hasBlinkAdPermission = () =>
currentPrivacyPermissions.some(
(permission) =>
permission.purpose?.match('processingpurpose:targeted_advertising') &&
permission.data?.some((entry) => entry.match('datacategory:interests'))
);
If glimr consent changes at any point you can update it like this:
ads.glimr = {
enabled: findGlimrPermissions(),
};
If finn blink consent or user changes you can update it like this:
ads.finnBlink = {
enabled: hasBlinkAdPermission() && currentUser?.userId && currentUser?.uuid,
userId: currentUser?.userId,
uuid: currentUser?.uuid,
};
You can skip any fields if you don't have them and update just enabled
for example.
If device changes you can update it like this:
ads.device = device;
Loading ads
You are ready to load ads. On any page that you want ads to show you can call loadAds
like this:
ads.loadAds({
keywords: {
'aa-sch-context_keyword': adsKeywords,
'no-sno-news-sponsors': adTags,
},
pageType: 'article',
});
pageType
is required but you can skip keywords
if you don't want to pass any additional keywords.
Warning
- at the moment there is no way to clear already loaded ads, this functionality was not needed for MinMote but likely will be introduced with Tek and Pent
- you must use
_
character as a delimiter in target ids (e.g. front-ad-1
must be changed to front_ad_1
) this is currently a limitation of @sch-inventory/advertory