Skip to content

Feed & Timeline Injection

Injection inserts ads between the cards of a Voxel post feed, or between statuses in the timeline. You describe placements as rules — one per line — under Settings → Voxel Ads → Feed injection.

Post feeds and the timeline have separate rule lists and separate on/off switches, because they usually want different densities.

Rule syntax

One rule per line. Each rule is a list of key=value pairs separated by commas:

shortcode=[adrotate group="1"], position=1
shortcode=[adrotate group="2"], interval=4, max=3, target=.feedresults

Lines starting with # are comments.

Placement keys

Three mental models cover nearly everything:

Where does it go?

KeyMeaning
position=NA fixed slot, after the Nth card. position=0 leads the feed — the ad becomes the first cell.
interval=NEvery N cards.
row=NAfter the Nth row of a grid. Column count is detected live and re-detected on resize, so one rule covers desktop, tablet and mobile.
row_interval=NAfter every Nth row, same column awareness.
start=NThe first slot when using interval. Defaults to the interval itself.
max=NCap how many times this rule fires per feed render.

What gets shown?

ShortcodeBehaviour
[adrotate banner="19"]One specific banner.
[adrotate group="2"]AdRotate picks at random from the group, per render.
[adrotate group="2"] with explode=yesOne banner per slot, in your chosen order — see below.

Everything else

KeyMeaning
colspan=NMake the ad span N grid columns. Clamped to the live column count, so it can never overflow.
priority=NWhen two rules compete for the same slot, the higher priority wins.
enabled=noSwitch a rule off without deleting it.
target=.selectorRestrict the rule to one feed.
geo=, terms=, days=, hours=Targeting.

interval=1 means every card

interval=1 and row_interval=1 place an ad after every item or row — not "one ad total". For a single insertion use position=N or row=N.

Targeting one feed

Without target, a rule applies to every feed matching the default container selector. On a site with several archives, that's rarely what you want.

target takes a CSS selector for the feed's container:

shortcode=[adrotate group="3"], interval=4, target=.places-feed
shortcode=[adrotate group="2"], interval=6, target=.events-feed

Give each Elementor post-feed widget its own CSS class and you can run completely different ad strategies per archive.

Explode mode

By default, [adrotate group="2"] asks AdRotate to pick a banner at random each time a slot renders. The same banner can appear twice in one feed, and a low-priority banner can outrank a premium one by chance.

explode=yes changes that: the group is expanded into one slot per banner, each getting its own placement.

shortcode=[adrotate group="2"], explode=yes, interval=4, order=priority
orderResult
priority (default)Sorted by voxel:priority, highest first. Banners on equal priority are shuffled among themselves, so equal-paying advertisers rotate fairly.
randomFully shuffled, priority ignored.

Explode mode is the setting that makes tiered pricing meaningful — it's what guarantees a Gold advertiser lands above a Bronze one rather than winning a coin toss.

Expired banners never take a slot

Explode mode only selects banners inside their live schedule window, so an expired campaign can't occupy a position. Voxel Ads also strips AdRotate's "advert not available" response before rendering, so an expired ad never leaves a blank labelled box in the feed.

Rows and columns

Voxel's post feed is a CSS grid, and the number of columns changes with screen width. Rules using row or row_interval detect the live column count and recalculate on resize and after "load more" — so row=1 means "after the first visible row" at every screen size, without you writing breakpoints.

colspan makes an ad span multiple columns:

shortcode=[adrotate banner="19"], row=1, colspan=2, target=.rowfeed

Pair colspan with row rather than position, so the wide slot starts at a row boundary and leaves no gaps. Colspan slots render as a fixed-height band (300px by default, override --vxad-colspan-height) showing the leaderboard creative — a rectangle can't fill a wide slot without cropping.

Colspan applies to CSS-grid feeds. On the timeline, which is a flex list, it's ignored.

The timeline

The timeline uses the same syntax, in the Timeline rules box:

shortcode=[adrotate group="2"], interval=5

Voxel's timeline is a Vue component, so the default selectors are tuned to insert at the right sibling level and inherit Voxel's status-card styling. Leave them alone unless you've customised the timeline markup.

Styling the ad card

Every injected ad renders inside a .vxad-card — a label plus the banner — so feed and timeline ads look identical regardless of the host feed's own markup.

Out of the box the card is frameless: transparent, no border, no padding, so the banner sits flush. Settings → Voxel Ads → Ad card styling exposes background, border, radius, padding, vertical alignment, and the "ADVERTISEMENT" label's text, colour, size and alignment.

For finer control, override the CSS variables:

css
:root {
  --vxad-card-bg: transparent;
  --vxad-card-border: 0;
  --vxad-card-radius: 10px;
  --vxad-card-padding: 0;
  --vxad-colspan-height: 300px;
}

Recipes

A hero ad above everything, plus rotation throughout

shortcode=[adrotate banner="42"], position=1, target=.feedresults
shortcode=[adrotate group="2"], explode=yes, interval=5, start=5, order=priority, target=.feedresults

A wide featured ad at the first row boundary

shortcode=[adrotate banner="19"], row=1, colspan=2, target=.rowfeed

Lead the feed — an ad before the first card

shortcode=[adrotate banner="19"], position=0, colspan=2, target=.rowfeed

Two tiers at different densities

shortcode=[adrotate group="3"], explode=yes, interval=4, max=3, target=.feedresults
shortcode=[adrotate group="2"], explode=yes, interval=7, max=2, target=.feedresults

Everything at once

shortcode=[adrotate group="2"], explode=yes, interval=5, start=3, max=4, colspan=2, order=priority, priority=10, geo=US;region:California, terms=restaurants;bars, days=fri;sat;sun, hours=11-23, target=.places-feed

Choosing the right key

GoalUseDon't use
One ad after card Nposition=Ninterval
One ad after row Nrow=Nrow_interval
Repeating every N cardsinterval=Nposition
Repeating every N rows, responsiverow_interval=Ninterval
A wide featured adcolspan=N + row=Nrow alone
Premium tiers rankedexplode=yes, order=priorityexplode=no
Each banner exactly once, random orderexplode=yes, order=randomexplode=no
Different rules per archivetarget= per rule

Global cap

Max injections per feed caps the total across every rule, as a backstop against a mis-typed interval filling a feed with ads. It applies after individual rule max values.

Built by Code Wattz.