Interstitial ads: full-screen, frequency capping. Use when: implementing full-page overlays, between-page transitions, frequency cap per session/user.
AdUnit.ad_format = "interstitial" placementsAdsSettings or Campaign settingsAdEvent records{# templates/ads/fragments/interstitial.html #}
<div x-data="interstitialAd('{{ placement.slot_id }}', { skipDelay: 5 })" x-cloak
x-show="visible"
class="fixed inset-0 z-50 flex items-center justify-center bg-black/80">
<div class="relative bg-[var(--color-bg-primary)] rounded-lg max-w-2xl w-full mx-4 p-6">
{# Skip button — appears after delay #}
<button x-show="canSkip"
x-transition
@click="dismiss()"
class="absolute top-3 right-3 px-3 py-1 text-sm
bg-[var(--color-bg-tertiary)] rounded hover:bg-[var(--color-bg-hover)]">
Skip Ad <span x-text="countdown" x-show="countdown > 0"></span>
</button>
<div class="ad-content" data-slot="{{ placement.slot_id }}">
{{ placement.render_code|safe }}
</div>
</div>
</div>
# apps/ads/services/targeting.py
from apps.ads.models import AdEvent
def check_interstitial_cap(*, user_id: int, daily_limit: int = 3) -> bool:
"""Return True if user can see another interstitial today."""
today_count = AdEvent.objects.filter(
user_id=user_id,
event_type="impression",
ad_format="interstitial",
created_at__date=timezone.now().date(),
).count()
return today_count < daily_limit
& .\.venv\Scripts\python.exe -m ruff check . --fix
& .\.venv\Scripts\python.exe -m ruff format .
& .\.venv\Scripts\python.exe manage.py check --settings=app.settings_dev