Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Adment Laravel Package

usamamuneerchaudhary/adment

Adment is a Laravel admin panel package that streamlines building back-office dashboards and internal tools, offering CRUD resources, authentication, roles and permissions through a clean, configurable interface so you can focus on your application's core logic.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Confirm the constraint before anything else. Adment targets Filament v5. If your panel is on Filament v3/v4, stop here — you'd be downgrading your whole admin stack to adopt a 10-star ad manager. Check the package's composer.json for the exact filament/filament and laravel/framework ranges; also confirm PHP version and that livewire/livewire v4 (the v5 companion) is what you're on.

composer require usamamuneerchaudhary/adment
php artisan vendor:publish --tag="adment-config"
php artisan vendor:publish --tag="adment-migrations"
php artisan migrate

2. Register the plugin in your panel provider. This is the step people forget; without it you get no admin UI and assume the package is broken.

use Usamamuneerchaudhary\Adment\AdmentPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugin(AdmentPlugin::make());
}

3. Look at these files first, in this order:

Path Why
config/adment.php Caching, tracking toggles, AdSense client ID, route prefix — everything you'll tune
database/migrations/* The real schema: placements, creatives, and likely impressions/clicks. Read this before designing anything
src/Models/* Relationship names and scopes; this is your actual API
src/Http/ or routes/ The public API and click-tracking endpoint shapes
resources/views/ The Blade components you'll drop into layouts

4. First use case — the 20-minute win. Create a placement in the admin (a named slot: header-banner, sidebar-300x250, in-article), attach one or more creatives to it, then render the placement in your Blade layout by key. That placement-key indirection is the package's core value: your templates reference header-banner, not an ad unit ID, so swapping AdSense ↔ direct-sold creative never touches a view.

{{-- indicative shape — confirm the component/helper name in resources/views --}}
<x-adment::placement name="header-banner" />
{{-- or --}}
@adment('header-banner')

Ship one placement, verify an impression lands in the DB, then roll out.

Implementation Patterns

Placement-first, always. Treat placements as the contract between marketing and code, and creatives as content. Never hardcode a creative ID in a Blade file. When you need a new ad slot, the workflow is: dev adds @adment('new-slot') → marketer creates the placement with that key → done. Budget one PR per slot, not per campaign.

AdSense mode vs. self-hosted creatives. Typically a placement is either backed by an AdSense unit (script + <ins> tag, client ID from config) or by rotating local creatives. Keep this decision in the placement record, not in code, so you can switch a slot to a house ad during a slow sales month without a deploy. Store the AdSense slot ID on the placement/creative and the publisher ID in config/env — never commit the publisher ID.

Responsive creatives. Do the responsive work with srcset/sizes and an explicit aspect ratio on the wrapper, not with JavaScript measurement. Two practical patterns:

  • One creative per breakpoint attached to a placement, with the renderer picking by container width via CSS media queries.
  • A single creative with multiple asset sizes stored, letting the browser choose.

Either way, always reserve space so the ad never causes CLS.

Click tracking without write amplification. If clicks go through a redirect route, expect a row-insert per click. On any page with real traffic that's a hot table. Mitigations, in order of preference:

  1. Turn on the package's cache/aggregate option if offered in config.
  2. Push click recording to a queued job (ShouldQueue, batched) and keep the redirect synchronous and fast.
  3. Prune aggressively — a scheduled model:prune on the click model with 30–90 days retention.
// AppServiceProvider::boot() — pattern, adjust to the package's model names
AdmentClicks::prune(); // or a scheduled command

Also decide where the impression is counted. If your pages are full-page cached (Cloudflare, spatie/laravel-responsecache), a server-rendered impression counter will undercount badly. Fire impressions from a tiny JS beacon against the public API instead, and skip counting for bots/referrer-less requests.

Public API + caching. The package exposes a JSON API for placements — this is the piece to lean on for SPAs, Inertia pages, and edge-cached fragments. Cache the placement payload (not the HTML) in Redis with a key derived from the placement key, and bust it from the placement/creative model's saved/deleted events:

// pseudo-hook
Placement::saved(fn ($p) => Cache::forget("adment:placement:{$p->key}"));

Then let the client render. This keeps the API cheap enough that you can call it on every page load.

Scheduling and rotation. Use whatever start/end/weight fields exist on creatives for campaign flights rather than doing it manually at deploy time. Add a scope like ->active() in your own code if the package doesn't ship one — you'll want it in every query.

Multi-panel / multi-tenant. Add a tenant_id/panel_id column via your own migration and a global scope if you run more than one panel. Don't fork the package for this; a global scope is enough for the admin queries and a where clause on the public API.

Gotchas and Tips

  • Version pinning is mandatory. 10 stars, zero dependents, latest release dated in the future relative to typical usage — this is a one-maintainer package. Pin an exact version ("usamamuneerchaudhary/adment": "1.2.3") and read src/ before trusting any README. Vendoring a copy is a legitimate choice for something this small.
  • CSP will silently kill AdSense. Add script-src for pagead2.googlesyndication.com / *.googlesyndication.com / *.google.com, frame-src for googleads.g.doubleclick.net, and img-src for the ad CDN. Symptom is a blank slot with only a console CSP violation — easy to misdiagnose as a package bug.
  • Ad blockers mean ~30% of your users see nothing. Never make layout depend on the ad rendering. Test with uBlock on as well as off — that's your real baseline.
  • Don't modify creatives client-side. AdSense policy prohibits it; resizing an <ins> element with CSS after render is a good way to get an account flagged. Style the container, not the ad.
  • Reserve dimensions. A placement without a fixed height/aspect ratio is the #1 cause of CLS regressions after installing this. Set min-height on the wrapper from the placement's configured size.
  • Config cache bites on install. php artisan config:cache before publishing config gives you null for every adment setting. Publish, verify, then re-cache.
  • Filament assets. php artisan filament:assets after install/upgrade, or the admin resource renders unstyled and you think the plugin registration failed.
  • Click route and middleware. The tracking redirect route needs to work for logged-out users and must not be caught by your auth middleware or CSRF assumptions. Whitelist it explicitly and exclude it from session/cookie middleware if you're on a strict stack — otherwise every click writes a session row.
  • N+1 in the admin table. Filament resources listing placements with creatives will lazy-load per row. Eager-load in the resource's table query; it's the difference between a fast list and a 4-second page.
  • Debugging checklist when a slot is empty: (1) is the placement active and within flight dates? (2) does a creative exist and is it enabled, (3) is the config ID set, (4) is the Blade component actually rendering (view-source, not devtools — JS may just be blocked), (5) check the impressions table for the placement ID.
  • Extension points worth knowing: model swapping via config (so you can add columns without forking), custom creative renderers/views, and model events on placements/creatives — those events are your cleanest cache-busting hook.
  • Write your own tests. Assume none ship. A feature test asserting the placement endpoint 200s and returns expected keys, plus one asserting the click route redirects and records a row, will save you on upgrade.
  • Have an exit plan. Because the surface area is small (a few tables, one Blade render, one redirect), a 150-line replacement is realistic if the package stalls. Keeping ad rendering behind your own App\Support\Ads facade from day one makes that swap a one-file change — strongly recommended for a dependency at this maturity level.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin