Japode Ads

A house ad network for the Japode and Viglet projects. Everything is static files on this domain: a catalogue, a loader and the logos. No ad server, no bidding, no third-party advertisers, and nothing about the reader is collected or stored.

Paste this

Two lines. The container marks where the banner goes; the script tag can sit anywhere.

<div data-japode-ads></div>
<script src="https://ads.japode.com/v1/ads.js" async></script>

That is a working slot. Every attribute below is optional and exists to narrow what it shows.

The four formats

One campaign entry, four layouts. Each rearranges the same fields rather than asking the advertiser for new ones, and each is fluid inside whatever column you give it — the widths below are deliberately different. Every unit here is live.

footer — a wide leaderboard
in-content — a rectangle inside an article
sidebar — a tall column
strip — one compact line

Narrow your window: the row formats become columns when their slot gets tight, not when the screen does. A sidebar is narrow on a wide screen too.

Build a snippet

Which layout family to draw. The catalogue names the same four.
Your own label for this placement. Defaults to the format plus its position.
Which half of a campaign's brand tokens to use. auto follows the reader.
Leave blank to inherit the page's own language.
Comma separated. Blank means no filter.
Campaign ids to keep out of this slot — how a project avoids advertising itself.

Live slot

A real container on this page, driven by the same loader you would paste.

What the loader made of this page:

reading…
Every slot on this page is the real thing. They run the loader this page tells you to paste, against the live catalogue, with no preview mode and nothing mocked — which is also how the banner gets tested: if it is broken here, it is broken everywhere. Reload and the picks change: each slot draws at random, weighted by the catalogue, and no two slots on a page draw the same product.

Attributes

AttributeValuesDefaultWhat it does
data-japode-adsrequired Marks the element as a slot. Its presence is the only thing required.
data-ad-format sidebar, in-content, footer, strip in-content The layout family — see the four above. An unrecognised value warns in the console and falls back rather than leaving your reader with nothing.
data-ad-slotany labelformat + position Names this placement so you can tell two slots apart.
data-ad-theme auto, light, darkauto Which half of the campaign's brand tokens to draw with.
data-ad-langa BCP 47 tagyour <html lang> Only campaigns written in this language. Set it to an empty value to accept any.
data-ad-tagscomma separatedno filter Only campaigns carrying one of these tags.
data-ad-excludecomma separated idsnone Campaign ids this slot must never show.

What you are agreeing to

The loader makes one request per page however many slots you place, and it never blocks rendering. The banner is drawn inside a shadow root, so your stylesheet cannot reach it and it cannot leak into your page. If the catalogue cannot be read for any reason, every slot collapses silently rather than leaving a broken frame.

There are no cookies, no identifiers and no third parties: the whole network is this domain serving static files, and nothing about your reader is ever sent anywhere.

The one thing that is stored is a list of the last four campaign ids a slot drew, with a timestamp, so a reader reloading does not meet the same banner every time. It expires after thirty minutes and it is written to your origin's localStorage, not ours — which means it cannot follow anyone between sites, and a reader on two of your pages and someone else's has two unrelated memories. If storage is unavailable, as in a private window, the draw simply happens without it.

Versioning

/v1/ads.js and /v1/catalogue.json answer v1 for as long as any snippet points at them. An incompatible change ships at /v2/ beside them and never in place — these snippets live in pages we cannot edit, so a v1 URL that stopped answering v1 is the one failure nothing here could repair.