Run your own advertising on your own site. Define the slots your theme offers, fill them with house banners, HTML blocks or a third-party ad tag, decide who sees what, and read the impressions and clicks in the admin panel.

Named Zones

Seven ready-made slots (header, before and after content, in-article, two sidebar slots and footer), each with its own size, rotation and limits.

Three Ad Formats

An uploaded banner, your own HTML, or the tag your ad network gave you. Mix all three in the same zone.

Targeting

Show an ad only on certain page types or URLs, in certain languages or countries, on certain devices, to guests or to specific roles.

Honest Numbers

Impressions, clicks and click-through rate per ad, zone and campaign, with bot traffic filtered out and a CSV export.

House ads and ad networks, not an advertiser marketplace. You create and manage every campaign yourself. Advertisers are contact details on a campaign, not accounts: they never sign in, never upload anything and never pay through the site.

Use Cases

Selling space directly to sponsors

The case the caps and the schedule were built for.

  • Give each sponsor a campaign with their contact details and the dates you agreed.
  • Cap the campaign at the number of impressions they paid for; it stops on its own when it gets there.
  • Send them the CSV export at the end of the month as proof of delivery.

Monetising with an ad network

Paste the network’s tag once per slot and let it run.

  • Ad network code waits for the visitor’s marketing consent, then loads without a page reload.
  • Rotate two networks in the same slot to compare them.
  • Show a house ad instead when an ad blocker swallows the network’s creative.

Promoting your own products

The cheapest advertiser is you.

  • Put an HTML block in the in-article slot of your blog and point it at a landing page.
  • Target it at signed-out visitors only, so customers are not sold something they already own.
  • Read the click-through rate to see which wording works.

Geographic and seasonal campaigns

Different creatives for different audiences, from one place.

  • Run one banner in France and another everywhere else.
  • Serve a narrow creative to phones and a wide one to desktops.
  • Schedule a seasonal campaign weeks ahead; it starts and stops by itself.

Requirements

  • Larapen CMS v1.0.0 or later
  • PHP 8.3+
  • MySQL 8.0+
Note: Ad Manager is fully standalone: it has no dependencies on other add-ons. It does make use of three of them when they happen to be installed: a cookie-consent add-on to hold back third-party ad code, an ad-blocker detector to trigger the fallback content, and a statistics add-on for its bot classifier. Each is optional, and the add-on works normally without any of them. Country targeting uses the GeoIP provider already configured in the core settings.

Installation

Step 1: Upload the Add-on

In the admin panel, go to Admin → Extensions → Add-ons and click the Upload Add-on button. Select the add-on’s ZIP file: the system extracts it automatically and the add-on appears in the installed add-ons list.

Step 2: Activate the Add-on

Find Ad Manager in the list and click Activate. Its migrations and permissions are set up automatically, seven ready-made zones are created, and a sample house campaign is added as a draft so you have something to look at.

Step 3: Place a Zone

Nothing is shown to visitors until a zone appears on a page. Either add a zone tag to your theme (see Adding a Zone to a Theme), or switch on automatic placement for the top or bottom of every page.

Purchase Code (License Key)

Ad Manager is sold as a separate product, so it has its own purchase code (license key), distinct from the purchase code of the main application and from the one of every other add-on. You are asked for it when you activate Ad Manager in Admin panel → Add-ons.

Our products are sold on three platforms. The way you receive a purchase code depends on where you bought the product.

Platform / Marketplace How you get the purchase code Where to find it again
bedigit.com Store
In-site purchase (Shop)
Generated automatically when the order is paid, then sent by email, either in its own license email, or inside the order confirmation email. My Account → My Licenses on bedigit.com
Gumroad Created as soon as Gumroad notifies us of the sale, then sent in a separate email, in addition to the Gumroad receipt. The license email, your Gumroad Library, and My Account → My Licenses on bedigit.com
Envato Market
CodeCanyon
Issued by Envato, not by us, and never sent by email: you download it yourself from your Envato account. Envato account → Downloads → License certificate & purchase code
Check your spam folder. For both bedigit.com Store and Gumroad purchases, the purchase code is delivered by email. Automated license emails are very often filtered, so if the message is not in your inbox, look in your spam / junk folder before contacting support, and add our sender address to your contacts or allow list.

1. bedigit.com Store (in-site purchase)

  • As soon as the order’s payment status becomes Paid, a license key is generated automatically for every licensed item in the order (one key per purchased unit: buying 3 units gives 3 distinct keys).
  • It is emailed to the address used on the order, either in a dedicated license email or inside the order confirmation email. Check your inbox and your spam / junk folder.
  • The key stays available in your account under My Account → My Licenses. Keys are masked in the list; open the license detail page to reveal and copy the full key, see the domains it is activated on, and deactivate a domain to free an activation slot.
  • The matching invoice is under My Account → My Orders.

2. Gumroad

  • A Gumroad purchase produces two separate emails: the Gumroad receipt (sent by Gumroad, giving access to the files) and a license key email (sent by bedigit.com) that contains your purchase code.
  • The license key email is generated as soon as Gumroad notifies us of the sale, so it normally arrives within seconds of the payment. Here too, check your inbox and your spam / junk folder.
  • When the Gumroad product uses Gumroad’s own license-key feature, the same key also appears in your Gumroad receipt and under Library in your Gumroad account.
  • The key is recorded on your bedigit.com account as well, under My Account → My Licenses.

3. Envato Market (CodeCanyon)

  • Envato issues the purchase code itself. We never send it by email, because we do not receive it.
  • Get it from your Envato account: Downloads → find the item → License certificate & purchase code (the text or PDF version both contain it).
  • It looks like xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
Still cannot find it? Open a ticket from our Help Center with the email address used for the purchase and, where applicable, the order number or the Gumroad receipt. We can look the key up for you.

Quick Start

Getting a first ad on screen takes about three minutes.

  1. Go to Admin → Ad Manager → Settings → Automatic placement and set Inject at the bottom of every page to Footer (bottom of page). Save.
  2. Go to Admin → Ad Manager → Campaigns and click New campaign. Name it, set the status to Active and save.
  3. Go to Admin → Ad Manager → Ads and click New ad.
  4. Pick HTML block, paste a little markup, and give it a destination URL.
  5. Open the Placement tab and tick Footer (bottom of page).
  6. Set the status to Active and save.

Open your site in a private window: the ad is at the bottom of the page. Come back to Admin → Ad Manager → Dashboard and the impression is already counted.

Nothing to set up first. Activating the add-on creates seven zones, ready to book ads into. On a demo installation a sample campaign with three creatives, one per format, is seeded as well; they are drafts, so nothing is shown to visitors until you switch them on, but they are a working example to read.

Zones

A zone is a named slot on your pages. It decides where an ad can appear, how many ads share the slot, how they take turns, and what is shown when there is nothing to show. Ads are never placed on a page directly: they are booked into zones.

Manage them under Admin → Ad Manager → Zones.

Built-in Zones

Seven zones are created when the add-on is activated. Rename them, resize them, deactivate the ones you do not need, and add your own.

Zone Key Suggested size Typical use
Header (top of page)header_top728×90A leaderboard above everything else
Before contentbefore_content728×90Between the header and the article
Inside articlein_article336×280Between two paragraphs of a long read
After contentafter_content728×90Below the article, above the comments
Sidebar (top)sidebar_top300×250The first thing in a sidebar
Sidebar (bottom)sidebar_bottom300×600A tall slot, showing two ads at once
Footer (bottom of page)footer_bottom970×90The last thing on the page
The key is the contract. A theme refers to a zone by its key, so renaming the zone is safe but changing its key means updating the theme. Keys are lowercase letters, digits and underscores.

Zone Settings

SettingWhat it does
Width / HeightThe size the slot expects. The height is reserved in the page before the ad loads, so nothing jumps around when it arrives.
Accepted formatsWhich of the three ad formats this slot will serve. An ad in any other format is never shown here, even if you book it in.
Ads shown at onceOne by default. Two or more turns the slot into a row of ads.
RotationHow the slot chooses between the ads booked into it. See below.
Show the “Advertisement” labelA small caption above the slot. Many jurisdictions require advertising to be identified as such; the wording is configurable site-wide.
Load when scrolled into viewKeeps the ad off the critical path, so it does not slow the page down. Turn it off for a slot that is visible as soon as the page opens.
Insert after paragraphOnly used by in-content placement: how many paragraphs to skip before dropping the slot in.
Extra CSS classesAdded to the slot wrapper, for theme-specific spacing.
Fallback contentShown when there is nothing to serve, or when an ad blocker removed the creative. See Ad Blockers.

Rotation modes

  • Random: every eligible ad has the same chance on every page view.
  • Weighted: ads are drawn in proportion to their weight. An ad’s weight is multiplied by its campaign’s, so you can set a share once per sponsor and still split it between their creatives.
  • Sequential: the ads take turns, one after another, in order.

Adding a Zone to a Theme

Zones appear where your theme puts them. Open the template you want to advertise on and drop in the zone tag. Both forms below do exactly the same thing, use whichever reads better where you are:

<x-admanager::zone key="sidebar_top" />

{!! ad_zone('sidebar_top') !!}

Each zone’s exact tag is on its edit page, with a copy button, and in the zone list. A few things worth knowing:

  • The tag renders nothing at all, not even an empty wrapper, when the zone is unknown, switched off, has no ad to serve, or the visitor is ad-free. You never need to guard it with a condition.
  • Add spacing with the class attribute: <x-admanager::zone key="sidebar_top" class="my-5" />.
  • A page can carry as many zones as you like, and the same zone twice if that makes sense in your layout.
  • Everything the slot needs, its styles and its small script, is added to the page automatically, once, however many zones there are.

Inside an article

The in-article slot goes between two paragraphs of content someone has written, which a template tag cannot do on its own. Wrap the content instead:

{!! ad_zone_in_content($post->content, 'in_article') !!}

The zone is inserted after the number of paragraphs configured on it (three by default). If the content has fewer paragraphs than that, the slot goes at the end rather than being dropped. When the add-on is switched off, or the zone has nothing to serve, the content comes back untouched.

Ready-Made Placements

The pages of the Blog, Forum, Glossary, Classified Ads, Events and Careers add-ons already carry the zones, in every bundled theme. As soon as you book an ad into one of these zones, it shows there; there is no template to edit. On a site without Ad Manager, these pages look exactly as before.

PageZones
Blog post, glossary term, classified ad, eventbefore_content, in_article, after_content, sidebar_top, sidebar_bottom
Job offerbefore_content, in_article, after_content, and sidebar_top above the job details (they stay in view while scrolling, so there is no bottom sidebar slot on this page)
Forum threadbefore_content, in_article, after_content, plus the forum sidebar zones
Blog, glossary, classified, event and job listingsbefore_content above the list, after_content below it, and the sidebar zones where the page has a sidebar
Forum home, categories and searchbefore_content, after_content, sidebar_top, sidebar_bottom
Blog homebefore_content below the trending headlines, after_content above the topics

The in-article slot only goes into the main text of the page: the body of a post, a term’s extended explanation, a listing’s or an event’s description, a job description, or the first post of a forum thread (never the replies). The sidebar slots sit below the page’s main card, such as Contact the seller or Register, so the ad never pushes that card down. The job page is the exception: its details card follows the reader down the page, so its ad sits above it.

Aim a zone at one kind of page. The same zone key is used on every page, so a sidebar ad booked into sidebar_top shows on all of them. Use page-type targeting to keep an ad to, say, job offers only.

Tools Pages

The tool add-ons (image tools, PDF tools and so on) have their own two ad placements, at the top and at the bottom of their pages, managed in each tool group’s Settings → Ads tab. When Ad Manager is active, each placement there gets an Ad source choice:

  • Ad code: the ad code pasted in that tab, as before. This is the default.
  • Ad Manager zone: the placement shows what Ad Manager serves in the zone you pick. By default the top placement uses before_content and the bottom one after_content; pick any other zone, or create zones just for the tools pages if you want to sell them separately.

The placement’s Show on switches (tools list page, tool page) still decide where it appears. If the zone has nothing to show, the pasted ad code is used instead, so you can keep a network ad as a fallback. To keep an ad on the tools pages only, target the Tool hubs and Tool pages page types, or pick one or more tool groups to reach only those tools.

Paying users. On the tools pages, the tools’ own switches decide whether users with credits or a subscription see ads, also for ads served by Ad Manager. The ad-free roles set in Ad Manager still apply.

Automatic Placement

If you would rather not edit a template at all, two settings under Admin → Ad Manager → Settings → Automatic placement put a zone at the very top or the very bottom of every page on the site:

  • Inject at the top of every page: placed right after the opening body tag.
  • Inject at the bottom of every page: placed just before the closing body tag.

Both are off by default, and both are independent of any zone tag your theme already carries: a site can use one, the other, or both. Admin panel pages are never touched.

Ads

An ad is one creative: a banner, a block of HTML, or an ad network tag. Every ad belongs to a campaign and is booked into one or more zones.

Create them under Admin → Ad Manager → Ads. The form has three tabs: the Creative, its Placement, and its Targeting.

Image Banners

The classic format. Pick the creative from the media library, give it a destination URL, and the add-on takes care of the rest.

  • An optional mobile banner is shown instead of the main one below 576px, so a wide leaderboard does not shrink to an unreadable strip on a phone.
  • Alt text is translatable and describes the banner to screen readers and to anyone whose images fail to load.
  • The creative’s real dimensions are read on save and written into the markup, so the browser reserves the right space and the page never jumps as the image arrives. Where the media library has generated smaller copies of the image, they are offered to the browser too, so a phone downloads a phone-sized file.
  • Clicks go through a short tracking hop before landing on the destination, which is what makes the click figures possible.

HTML Blocks

Your own markup: a text ad, a promo box, a styled card: anything you can write. It is rendered exactly as you typed it.

  • Give it a destination URL and the whole block becomes a tracked link. Leave the URL empty and it is shown as-is, untracked, useful for a notice rather than an ad.
  • Because the block is wrapped in a link when you give it a URL, do not put a link of your own inside it.

Ad Network Code

The tag your ad network gave you, pasted verbatim. The network draws the ad and counts its own clicks.

  • Impressions are still counted on your side, so you can compare the network’s figures with your own.
  • Clicks are not: the network’s tag brings its own link, which never passes through this add-on. Read those in the network’s dashboard.
  • This is the one format that waits for cookie consent. See Cookie Consent.
Ad code is executed, not displayed. HTML blocks and network tags are rendered raw, so a <script> in them runs on every page carrying the ad: that is the whole point of an ad tag, and it is the same trust level as your theme’s “Custom JS” setting. Only paste code from a source you trust, and give the Edit ads permission only to people you would give that setting to.

Other ad settings

  • Link rel: search engines expect a paid link to carry sponsored. The site-wide default is used unless you override it on the ad.
  • Open in a new tab: on by default, so your visitor keeps the page they were reading.
  • Weight: the share of a weighted rotation this creative takes.
  • Order: breaks ties between ads, lowest first.
  • Preview: opens the creative on its own so you can check it before it goes live. A preview never counts an impression.
  • Duplicate: copies the ad and its zone bookings as a draft, for a quick variant.

Campaigns & Caps

A campaign groups ads under an advertiser, a schedule and a budget. Every ad belongs to one. If you are only running house ads, a single campaign called “House ads” is perfectly reasonable.

The advertiser

Name, email, phone, website and a free-text note. These are contact details for your own reference: advertisers have no account, cannot sign in, and never see the admin panel.

The schedule

Starts and Ends are both optional. A campaign with neither runs for as long as its status is Active. A campaign that has not started yet, or whose end date has passed, serves nothing: you do not have to remember to switch it off.

The caps

Four optional limits, any combination of which can be set:

CapWhat happens when it is reached
Impressions per dayThe campaign pauses for the rest of the day and resumes by itself the next morning.
Clicks per daySame: paused until tomorrow.
Impressions in totalThe campaign is marked Completed. It is done.
Clicks in totalSame: completed for good.

The campaign list shows why a campaign stopped on its own, and the edit page repeats it. To restart a completed campaign, raise or clear the cap and set its status back to Active.

Caps are budget guards, not accounting. To avoid a database query on every page view, the daily figure a cap is checked against is refreshed about once a minute. A busy site can therefore overshoot a daily cap slightly. Set the cap a little under the number you sold if the exact figure matters.

Weight and priority

  • Weight multiplies the weight of every ad in the campaign, in zones set to weighted rotation. One sponsor buying twice the share of another needs one number changed, not five.
  • Priority breaks ties between campaigns; higher comes first.

Targeting

Targeting narrows who sees an ad and where. It lives on the ad, on its Targeting tab.

Empty means everywhere. Every axis left empty places no restriction at all. The axes you do fill in must all match: an ad targeted at blog posts and France shows only on blog posts read from France.

Pages & URLs

Page types

Broad buckets rather than individual pages: the home page, static pages, blog posts, blog listings, shop products, shop listings, cart and checkout, tool pages, the forum, glossary terms and listings, classified ads and listings, events and event listings, job offers and job listings, the portfolio, courses, account pages, sign-in pages, and everything else. Pick as many as you like; leave the field empty to run on all of them.

Under Tool groups, the picker also lists each installed tool add-on (Image Tools, PDF Tools and so on), to run an ad on one group of tools only. These add to the page types rather than replace them: a page of the image tools counts as Tool pages and Image Tools, so an ad aimed at every tool page keeps showing there.

Buckets whose section is not installed simply never match, so leaving “Shop products” ticked on a site with no shop is harmless.

URL patterns

For anything a bucket is too coarse for. One pattern per line; an asterisk matches anything:

/blog/*
/pricing
/shop/*/reviews

An ad matches if any of its patterns matches the page’s path. Patterns are matched against the path only (no domain, no query string) and the language prefix is part of the path, so /fr/blog/* targets the French blog specifically while */blog/* covers every language.

Country, Device, Audience

Languages

Restrict an ad to one or more of the site’s active languages. A French creative should usually be targeted at fr rather than relying on the URL.

Countries

Resolved from the visitor’s IP address, using the GeoIP provider configured under Admin → Settings → GeoIP. Switch Treat as an exclusion list on to flip the meaning: the ad then runs everywhere except the countries you picked.

A visitor whose country cannot be determined counts as “not in the list”: an inclusion list excludes them, an exclusion list keeps them. That is the reading that never shows a geo-restricted ad to the wrong audience.

Country targeting needs a working GeoIP provider. The lookup result is cached per visitor for an hour, and it is skipped entirely when no ad in the zone targets a country, so a site that does not use this axis pays nothing for it. If none of your geo-targeted ads ever appear, check the GeoIP settings first: a provider with an expired API key returns no country, and every inclusion list then matches nobody.

Devices

Desktop, tablet and mobile, read from the browser’s user agent. Tick none to run everywhere.

Audience

  • Everyone: the default.
  • Signed-out visitors: the right choice for an ad selling something your customers already have.
  • Signed-in users: for an upsell or a members-only announcement.
  • Specific roles: pick the roles the ad is for.

Dashboard

Admin → Ad Manager → Dashboard answers the only two questions that matter: how often was it seen, and how often was it clicked.

  • Four headline figures for the selected range: impressions, unique views, clicks and the resulting click-through rate.
  • A daily chart of impressions against clicks, so a spike or a drop is obvious.
  • A breakdown you can flip between by ad, by zone and by campaign.
  • Filters for the date range, and for one zone, campaign or ad at a time.
  • Export CSV gives you one line per day, ad and zone for whatever the filters currently show: ready to send to a sponsor or open in a spreadsheet.

Each ad’s own running totals are also on the ads list, and each campaign’s on the campaign list, so you rarely need to open the reports to see how something is doing.

How Counting Works

Impressions

Two modes, under Admin → Ad Manager → Settings → Tracking:

  • When the page renders it (the default): counted on the server as the slot is built. It needs no JavaScript and no ad blocker can suppress it, but it counts ads further down the page that the visitor may never have scrolled to.
  • When the visitor scrolls to it: counted by the browser once the slot is actually on screen. Closer to what an advertiser means by an impression, at the price of missing visitors who block scripts.

Clicks

A click on a banner or an HTML block goes through a short redirect that records it and forwards the visitor to the advertiser. Network tags count their own clicks and are not measured here.

Unique views and unique clicks

“Unique” means the first time today that a given visitor saw or clicked a given ad in a given slot. Visitors are recognised by a one-way fingerprint of their IP address and browser, which is never stored, only the fact that it was already seen today, and only until midnight.

Uniques are a good-faith figure. The markers live in the site cache, so clearing the cache part-way through a day resets them and the day’s unique counts come out a little high. Impressions and clicks themselves are unaffected.

Bots

Crawlers are recognised and left out of both figures. When a statistics add-on is installed, its much more thorough classifier is used instead of the built-in one: published crawler ranges, hosting-provider ranges and clients that claim to be a browser but do not behave like one. You can switch the filter off under Settings → Tracking if you would rather see raw traffic.

What is stored

Nothing per event. Every impression and click is folded straight into a single row per day, ad and zone, so the reporting tables grow with the size of your catalogue rather than with your traffic. Rows older than the retention window (400 days by default) are pruned nightly.

Cookie Consent

Third-party ad code sets cookies and calls out to an ad network, which in most of Europe requires the visitor’s consent first.

When a cookie-consent add-on is installed and Wait for cookie consent is on:

  • Ad network tags are not sent to the browser at all until marketing cookies are accepted. Not hidden with CSS, not loaded and paused: simply absent from the page.
  • Image banners and HTML blocks are unaffected: they set no cookies and call nothing out.
  • The moment the visitor accepts, the slots that were holding an ad back fetch their content and fill themselves in, without a page reload.
  • A visitor who declines simply never sees those slots.

With no cookie-consent add-on installed there is no consent to honour, and ad code is served normally. The setting page says so explicitly, so you are never left wondering whether it is doing anything.

Ad Blockers

An ad blocker strips the creative out of the page but leaves the slot behind, which is how you end up with a gap where an ad used to be.

Give a zone some Fallback content and that gap becomes useful instead. Shortly after the page settles, a slot whose ads have all been reduced to nothing reveals the fallback:

  • A house ad for one of your own products.
  • A polite note asking the visitor to allow ads on your site.
  • A link to your ad-free plan, if you sell one.

The fallback is also what a zone shows when it simply has no ad to serve, so it is worth filling in even if ad blockers are not a concern.

The replacement only runs when an ad-blocker detector add-on is installed: it is the piece that tells us the site cares. Without it, a blocked ad leaves the slot empty, as before. You can also switch the behaviour off under Settings → Privacy.

Ad-free Visitors

Two groups of people never see an ad, whatever the targeting says.

Paying users

If your site sells credits or subscriptions, holders browse ad-free by default: the same rule the rest of the platform already applies, so the two can never disagree. Switch Hide ads from paying users off under Settings → Privacy if you would rather keep showing ads to everyone.

Chosen roles

List roles under Ad-free roles and their members never see an ad. Editors and staff are the usual candidates: they should see the site as it was authored, not as an advertiser sees it.

Administrators browsing the admin panel never see ads either: zones are not rendered there at all.

Multi-Language

The whole admin interface is translated into every language the platform ships.

On the ad itself, the alt text of a banner is translatable: pick the language in the selector above the field and fill in each one. An empty translation falls back to your default language.

Everything else about an ad is either not visible to the visitor (its internal name), or deliberately language-neutral (the creative, the destination URL). To run different creatives per language, create one ad per language and target each at its own language: that also lets you point them at different landing pages.

The “Advertisement” label above each slot follows the visitor’s language automatically, unless you override the wording site-wide under Settings → General.

Global Settings

Admin → Ad Manager → Settings, four tabs.

SettingDefaultWhat it does
General
Serve adsYesThe master switch. Off means no zone renders anything, anywhere.
Disclosure label“Advertisement”The caption above a slot. Leave empty for the translated default.
Default link relnofollow sponsored noopenerApplied to ad links that do not set their own.
Keep statistics for400 daysOlder daily rows are pruned nightly. 0 keeps them forever.
Tracking
Count an impressionWhen the page renders itServer-side or viewport counting. See How Counting Works.
Ignore bot trafficYesKeeps crawlers out of the impression and click counts.
Privacy
Wait for cookie consentYesHolds back ad network code until marketing cookies are accepted.
Show a fallback when an ad is blockedYesReveals the zone’s fallback content when the creative was stripped.
Hide ads from paying usersYesCredit holders and subscribers browse ad-free.
Ad-free roles-Members of these roles never see an ad.
Automatic placement
Inject at the top of every pageOffPlaces a zone right after the opening body tag.
Inject at the bottom of every pageOffPlaces a zone just before the closing body tag.

Permissions

Sixteen permissions are registered on activation and granted to the administrator role. Assign them to other roles under Admin → Users → Roles.

PermissionGrants
admanager.ads.viewSee the ads list and the add-on’s menu at all
admanager.ads.createCreate and duplicate ads
admanager.ads.editEdit ads, including their HTML and ad network code
admanager.ads.deleteTrash, restore and permanently delete ads
admanager.campaigns.viewSee campaigns
admanager.campaigns.createCreate campaigns
admanager.campaigns.editEdit campaigns, including their caps
admanager.campaigns.deleteTrash, restore and permanently delete campaigns
admanager.zones.viewSee zones
admanager.zones.createCreate zones
admanager.zones.editEdit zones, including their fallback content
admanager.zones.deleteDelete zones
admanager.reports.viewRead the reports
admanager.reports.exportDownload the CSV export
admanager.settings.viewOpen the settings page
admanager.settings.editSave the settings
Treat admanager.ads.edit and admanager.zones.edit as trusted. Both allow scripts to be placed on every page of the site, which is exactly what an ad tag is. Grant them the way you would grant access to the theme’s custom JavaScript.

Updating

Step 1: Upload the New Version

Go to Admin → Extensions → Add-ons, click Upload Add-on and pick the new ZIP. The existing files are replaced in place; your zones, campaigns, ads and statistics are not touched.

Step 2: Run Migrations

php artisan migrate

Step 3: Clear Caches

php artisan config:clear
php artisan route:clear
php artisan view:clear

Step 4: Verify

Visit Admin → Ad Manager → Ads to confirm the add-on is working correctly, and open a page carrying a zone on the front end to check an ad still appears.

Backup first: Always back up your database before running migrations on a production system. Your campaigns and all your statistics live in that database.

Deactivation

Switching an add-on off without losing anything is a deactivation: go to Admin panel → Add-ons, find Ad Manager and click Deactivate.

  • Its routes, views, admin menu entries and permissions stop being registered, and no ad is served anywhere.
  • Zone tags left in your theme render nothing at all rather than breaking: a deactivated add-on leaves no gap and no error behind.
  • The click-through and tracking endpoints stop answering.
  • Its database tables and all the data they hold are kept (your zones, campaigns, ads and every statistic) and its files stay under extensions/addons/admanager/. Nothing is deleted.
  • The purchase code recorded at activation is kept too, so activating the add-on again does not ask for it.
  • Deactivation is refused while another active add-on depends on this one: deactivate that add-on first.

Click Activate on the same card to switch it back on. Pending migrations are re-run, assets are republished, and the add-on picks up exactly where it left off, including every campaign that was running.

Removing

Removing is permanent and destroys the add-on’s data. The Remove button only appears on a deactivated add-on, so removal is always two steps:

  1. Deactivate Ad Manager (see Deactivation).
  2. Click Remove on its card and confirm the prompt.

The admin panel then, in one pass:

  • runs the add-on’s uninstall hook, if it ships one, while its code is still on disk;
  • revokes the permissions declared in its addon.json;
  • rolls back its migrations (this drops its database tables and every row they hold, including all your zones, campaigns, ads and the whole statistics history) and purges its entries from the migrations table, so a later reinstall migrates from scratch;
  • deletes its published assets: public/addons/admanager/, public/vendor/admanager/ and storage/app/public/addons/admanager/;
  • deletes the add-on directory extensions/addons/admanager/;
  • deletes its row in the addons table (the recorded purchase code goes with it) and clears the application cache.
This cannot be undone. Export what you need first: Admin → Ad Manager → Dashboard → Export CSV, over the widest date range, gives you a copy of every figure ever recorded. Banner files live in the media library and are not touched, but the ads pointing at them are. Installing the add-on again later creates empty tables, not your old campaigns.

Removal is refused, with an explanatory message and before anything is destroyed, when the add-on is still active, when another active add-on depends on it, or when the web server (PHP) user cannot delete extensions/addons/admanager/. In that last case, give that user write permission on the directory and on its parent, then try again.

Deleting the folder over FTP or SSH is not equivalent: the add-on’s tables, its entries in the migrations table and its addons row are all left behind, and its card stays in the list. Use Remove in the admin panel instead.

Zone tags you added to your theme are yours and are never touched. They render nothing once the add-on is gone, so you can leave them in place if you might install it again.

Troubleshooting

No ad appears anywhere

  • Check Serve ads is Yes under Admin → Ad Manager → Settings.
  • Check the ad’s status is Active, a new ad starts as a draft, and that its campaign is Active too. Both have to be.
  • Check the campaign’s dates: one that has not started, or that has ended, serves nothing.
  • Check the ad is booked into at least one zone, on its Placement tab.
  • Check the zone is active and that it actually appears on the page, either through a tag in your theme or through automatic placement.
  • Look at the page while signed out. You may be in an ad-free role, or holding credits.

One particular ad never shows

  • Open its Targeting tab and clear every axis, then add them back one at a time. The axes are combined with AND, so two reasonable-looking restrictions can easily exclude everyone.
  • Check the zone’s Accepted formats includes the ad’s format.
  • If the zone shows one ad at a time and several are eligible, they are taking turns: reload a few times, or set the rotation to sequential to watch them cycle.
  • Check the campaign has not hit a cap: the campaign list says so in plain words.

A geo-targeted ad shows nowhere

  • Check the GeoIP provider under Admin → Settings → GeoIP actually returns a country. With no provider configured, every inclusion list matches nobody.
  • Country lookups are cached for an hour per visitor, so a provider you have just fixed takes effect gradually. Clear the site cache to see it immediately.
  • On a local or intranet site, visitors have private IP addresses that cannot be geolocated at all.

An ad network tag shows nothing

  • Check the visitor has accepted marketing cookies: that is the one format that waits. See Cookie Consent.
  • Check the zone accepts the Ad network code format.
  • Ad blockers hide network tags aggressively. Test in a browser with no extensions.
  • Many networks need their domain approved before they serve anything. Check the network’s own dashboard first: a tag that is not yet approved renders an empty box everywhere, not just here.

The impression count looks too high

  • By default an impression is counted when the page renders the slot, whether or not the visitor scrolled to it. Switch Count an impression to When the visitor scrolls to it under Settings → Tracking for the stricter figure.
  • Check Ignore bot traffic is on. Installing a statistics add-on gives the filter a much better classifier.
  • Your own visits count too unless your role is ad-free.

Clicks are not being counted

  • Ad network tags count their own clicks; those figures live in the network’s dashboard, not here.
  • An HTML block with a link of its own inside it bypasses the tracking hop. Give the block a destination URL instead and let the add-on wrap it.
  • Check the ad has a destination URL at all: without one there is nothing to click.

The page jumps as ads load

  • Fill in the zone’s Height. The slot then reserves that space up front.
  • For a slot that is visible as soon as the page opens, turn off Load when scrolled into view.

A campaign paused itself and I do not know why

  • The campaign list shows the reason under the status, and the edit page repeats it above the form.
  • A daily cap resumes by itself; a total cap or a passed end date does not. Raise or clear the cap, or move the end date, then set the status back to Active.

Ad Manager v1.0.0: Part of the Larapen CMS platform.

© BeDigit. All rights reserved.

Was this article helpful?

Thank you for your feedback!

Still need help? Create a support ticket

Create a Ticket
Sep 28, 2026