Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ads-sdk): attempt to integrate ads-sdk #1421

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 55 additions & 12 deletions clients/web/src/components/content-ads/content-ads.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { css } from '@emotion/css'
import { AdSlot } from 'components/programmatic-ad/freestar-ad-slot'
import { AdSlot } from 'components/programmatic-ad/mozads-ad-slot'

import { IABFixedSize } from '@mozilla-services/ads-sdk/dist/core'

const aboveTheFoldStyle = css`
margin-bottom: var(--spacing250);
Expand All @@ -17,26 +19,61 @@ const adRailStyle = css`
const belowTheFoldStyle = css`
margin-top: 4rem;
`
// Syndicated Article Freestar placement IDs
const ABOVE_THE_FOLD = 'getpocket_leaderboard_atf'
const BELOW_THE_FOLD = 'getpocket_leaderboard_btf'
const RIGHT_RAIL_1_ID = 'getpocket_right_rail_1'
const RIGHT_RAIL_2_ID = 'getpocket_right_rail_2'

export function AdAboveTheFold({ allowAds, targeting }) {
// Syndicated Article MozAds placements
const ABOVE_THE_FOLD_MARS_ID = "pocket_billboard_1"
const BELOW_THE_FOLD_MARS_ID = "pocket_billboard_2"
const ABOVE_THE_FOLD_MOBILE_MARS_ID = "pocket_mrec_1"
const BELOW_THE_FOLD_MOBILE_MARS_ID = "pocket_mrec_2"
const RIGHT_RAIL_1_MARS_ID = "pocket_skyscraper_1"
const RIGHT_RAIL_2_MARS_ID = "pocket_skyscraper_2"

let placements = {}
placements[ABOVE_THE_FOLD_MARS_ID] = IABFixedSize.Billboard,
placements[BELOW_THE_FOLD_MARS_ID] = IABFixedSize.Billboard,
placements[ABOVE_THE_FOLD_MOBILE_MARS_ID] = IABFixedSize.MediumRectangle
placements[BELOW_THE_FOLD_MOBILE_MARS_ID] = IABFixedSize.MediumRectangle
placements[RIGHT_RAIL_1_MARS_ID] = IABFixedSize.Skyscaper,
placements[RIGHT_RAIL_2_MARS_ID] = IABFixedSize.Skyscaper

export function BillboardAboveTheFold({ allowAds, targeting }) {
return allowAds ? (
<AdSlot
placementId={ABOVE_THE_FOLD_MARS_ID}
placementName={placements[ABOVE_THE_FOLD_MARS_ID]}
targeting={targeting}
instanceStyles={aboveTheFoldStyle}
/>
) : null
}

export function BillboardBelowTheFold({ allowAds, targeting }) {
return allowAds ? (
<AdSlot
placementId={BELOW_THE_FOLD_MARS_ID}
placementName={placements[BELOW_THE_FOLD_MARS_ID]}
targeting={targeting}
instanceStyles={belowTheFoldStyle}
/>
) : null
}

export function RectangleAboveTheFold({ allowAds, targeting }) {
return allowAds ? (
<AdSlot
placementName={ABOVE_THE_FOLD}
placementId={ABOVE_THE_FOLD_MOBILE_MARS_ID}
placementName={placements[ABOVE_THE_FOLD_MOBILE_MARS_ID]}
targeting={targeting}
instanceStyles={aboveTheFoldStyle}
/>
) : null
}

export function AdBelowTheFold({ allowAds, targeting }) {
export function RectangleBelowTheFold({ allowAds, targeting }) {
return allowAds ? (
<AdSlot
placementName={BELOW_THE_FOLD}
placementId={BELOW_THE_FOLD_MOBILE_MARS_ID}
placementName={placements[BELOW_THE_FOLD_MOBILE_MARS_ID]}
targeting={targeting}
instanceStyles={belowTheFoldStyle}
/>
Expand All @@ -46,15 +83,21 @@ export function AdBelowTheFold({ allowAds, targeting }) {
export function AdRailTop({ allowAds, targeting }) {
return allowAds ? (
<div className={adRailStyle}>
<AdSlot placementName={RIGHT_RAIL_1_ID} targeting={targeting} />
<AdSlot
placementId={RIGHT_RAIL_1_MARS_ID}
placementName={placements[RIGHT_RAIL_1_MARS_ID]}
targeting={targeting} />
</div>
) : null
}

export function AdRailBottom({ allowAds, targeting }) {
return allowAds ? (
<div className={adRailStyle}>
<AdSlot placementName={RIGHT_RAIL_2_ID} targeting={targeting} />
<AdSlot
placementId={RIGHT_RAIL_2_MARS_ID}
placementName={placements[RIGHT_RAIL_2_MARS_ID]}
targeting={targeting} />
</div>
) : null
}
47 changes: 47 additions & 0 deletions clients/web/src/components/programmatic-ad/mozads-ad-slot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import PropTypes from 'prop-types'
import { css } from '@emotion/css'
import { useTranslation } from 'next-i18next'

import { MozAdsPlacement } from '@mozilla-services/ads-sdk/dist/react'

const programmaticAdWrapperStyles = css`
display: flex;
flex-direction: column;
align-items: center;

.label {
font-family: var(--fontSansSerif);
font-size: 0.85rem;
line-height: 100%;
color: var(--color-textTertiary);
text-align: center;
margin: 0;
padding-bottom: 0.5rem;
width: 100%;
}
`

export function AdSlot({ placementId, placementName, targeting, instanceStyles }) {
const { t } = useTranslation()
const adLabel = t('ad:label', 'Advertisement')

return (
<div className={`${programmaticAdWrapperStyles} 'syndication-ad' ${instanceStyles}`}>
<MozAdsPlacement
placementId={placementId}
iabContentCategoryIds={targeting.Category}
fixedSize={placementName}
/>
<p className="label">{adLabel}</p>
</div>
)
}

AdSlot.propTypes = {
// A string of the ad unit placement, which are constants provided by ads-sdk
placementName: PropTypes.string.isRequired,
// An *optional* object of key/value pairs for targeting.
targeting: PropTypes.object,
// An *optional* classname to add to the ad container
instanceStyles: PropTypes.string
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ import { ArticleActions } from 'components/content-actions/article-actions'
import { SaveArticleTop } from 'components/content-saving/save-article'
import { SaveArticleBottom } from 'components/content-saving/save-article'

import { AdAboveTheFold } from 'components/content-ads/content-ads'
import { AdBelowTheFold } from 'components/content-ads/content-ads'
import { BillboardAboveTheFold } from 'components/content-ads/content-ads'
import { BillboardBelowTheFold } from 'components/content-ads/content-ads'
import { RectangleAboveTheFold } from 'components/content-ads/content-ads'
import { RectangleBelowTheFold } from 'components/content-ads/content-ads'
import { AdRailTop } from 'components/content-ads/content-ads'
import { AdRailBottom } from 'components/content-ads/content-ads'

Expand Down Expand Up @@ -139,6 +141,10 @@ export function SyndicatedArticle({ queryParams = validParams, locale }) {
const syndicatedFrom = publisherUrl ? publisherUrl : false
const ArticleLayout = isMobileWebView ? MobileLayout : Layout

// Prepare the correct ad format for the viewport size
const AdAboveTheFold = isMobileWebView ? RectangleAboveTheFold : BillboardAboveTheFold
const AdBelowTheFold = isMobileWebView ? RectangleBelowTheFold : BillboardBelowTheFold

// Prep save action
const onSave = (url, value) => {
dispatch(sendSnowplowEvent('syndicated.article.save', { url, value }))
Expand Down
Loading