Appearance
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=.feedresultsLines starting with # are comments.
Placement keys
Three mental models cover nearly everything:
Where does it go?
| Key | Meaning |
|---|---|
position=N | A fixed slot, after the Nth card. position=0 leads the feed — the ad becomes the first cell. |
interval=N | Every N cards. |
row=N | After 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=N | After every Nth row, same column awareness. |
start=N | The first slot when using interval. Defaults to the interval itself. |
max=N | Cap how many times this rule fires per feed render. |
What gets shown?
| Shortcode | Behaviour |
|---|---|
[adrotate banner="19"] | One specific banner. |
[adrotate group="2"] | AdRotate picks at random from the group, per render. |
[adrotate group="2"] with explode=yes | One banner per slot, in your chosen order — see below. |
Everything else
| Key | Meaning |
|---|---|
colspan=N | Make the ad span N grid columns. Clamped to the live column count, so it can never overflow. |
priority=N | When two rules compete for the same slot, the higher priority wins. |
enabled=no | Switch a rule off without deleting it. |
target=.selector | Restrict 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-feedGive 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=priorityorder | Result |
|---|---|
priority (default) | Sorted by voxel:priority, highest first. Banners on equal priority are shuffled among themselves, so equal-paying advertisers rotate fairly. |
random | Fully 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=.rowfeedPair 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=5Voxel'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=.feedresultsA wide featured ad at the first row boundary
shortcode=[adrotate banner="19"], row=1, colspan=2, target=.rowfeedLead the feed — an ad before the first card
shortcode=[adrotate banner="19"], position=0, colspan=2, target=.rowfeedTwo 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=.feedresultsEverything 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-feedChoosing the right key
| Goal | Use | Don't use |
|---|---|---|
| One ad after card N | position=N | interval |
| One ad after row N | row=N | row_interval |
| Repeating every N cards | interval=N | position |
| Repeating every N rows, responsive | row_interval=N | interval |
| A wide featured ad | colspan=N + row=N | row alone |
| Premium tiers ranked | explode=yes, order=priority | explode=no |
| Each banner exactly once, random order | explode=yes, order=random | explode=no |
| Different rules per archive | target= 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.

