smalk/laravel-ads 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

smalk/laravel-ads

最新稳定版本:v0.1.0

Composer 安装命令:

composer require smalk/laravel-ads

包简介

Server-side Smalk native-ad injection + AI-agent tracking for Laravel publishers.

README 文档

README

Server-side Smalk native-ad injection and AI-agent tracking for Laravel publishers.

Laravel 10 / 11 / 12 · PHP 8.1+

How it works

AI crawlers (ChatGPT, Perplexity, Claude, Gemini) do not execute JavaScript, so ads must already be present in the HTML your server returns — client-side injection is invisible to them. This package registers a middleware on the web group that intercepts each outgoing HTML response, calls the Smalk Ad Server to retrieve the active ad, and replaces the <div class="smalk-ads"></div> placeholder before the response leaves your server. A second stage fires an after-response tracking call so plain-HTTP AI agents — which also skip the JS tracker — are recorded in your Smalk dashboard.

Install

Step 1 — require the package

composer require smalk/laravel-ads

Step 2 — publish the config

php artisan vendor:publish --tag=smalk-config

Step 3 — set credentials in .env

SMALK_PROJECT_KEY=your-project-key
SMALK_API_KEY=your-api-key

Those two variables are the only mandatory ones. Everything else has a sensible default (see Configuration below).

Placing an ad

Add exactly one ad slot per page. Two options:

Option A — div placeholder (recommended)

Drop this once in your Blade layout (e.g. resources/views/layouts/app.blade.php), in the body at the point where the ad should appear:

<div class="smalk-ads"></div>

The middleware detects the div, fetches the active ad HTML from the Smalk Ad Server, and replaces it before the response is sent. If no ad is live for that URL, the div is left intact — do not remove it: Smalk uses its presence to verify the placement is installed.

Option B — Blade component

Use the component when you want to resolve the ad at render time, or when your layout is composed dynamically per-route:

<x-smalk-ad path="/{{ $currentPath }}" />

Omit path to let the component fall back to the current request URL.

One slot per page maximum. Multiple smalk-ads divs on the same page are not supported.

Configuration

After publishing, the config lives at config/smalk.php. Every value is driven by an environment variable.

Credentials

Env var Default Effect
SMALK_PROJECT_KEY Required. Workspace project key — sent with every ad request and used by smalk:freshness to hit /projects/{key}/ads/inventory/active-ad-urls/.
SMALK_API_KEY Required. Sent as Authorization: Api-Key … on all server-side calls.
SMALK_API_BASE https://api.smalk.ai/api/v1 Base URL for the Smalk API. Only change this for staging.

JS Tracker

Env var Default Effect
SMALK_JS_TRACKER_ENABLED true When true, the middleware appends <script src="…/tracker.js?PROJECT_KEY=…"> before </head> on every HTML response.
SMALK_TRACKER_CDN https://cdn.smalk.ai/tracker.js CDN URL for tracker.js. Not versioned by SRI — the script is a dynamic versioned asset matching the WordPress, Drupal, and Node plugins.

AI Agent Tracking

Env var Default Effect
SMALK_TRACKING_ENABLED true When true, the middleware fires an after-response POST /api/v1/tracking/visit/ for every request on the web middleware group. Never blocks the response.
SMALK_TRACKING_FORWARD_IP false When true, the visitor's IP (X-Real-IP / X-Forwarded-For) is forwarded to Smalk alongside User-Agent and Referer. Off by default — see GDPR note.

Ad Injection

Env var Default Effect
SMALK_ADS_ENABLED true When true, the middleware fetches and injects server-side ad HTML into the <div class="smalk-ads"> placeholder.
SMALK_ADS_CACHE_TTL 21600 max-age value (seconds) used in the Cache-Control header on ad-bearing paths. Default is 6 hours.

JSON-LD

Env var Default Effect
SMALK_JSONLD_REWRITE true When true, the middleware rewrites dateModified only within <script type="application/ld+json"> structured-data blocks to surface the ad content to AI engines via structured data, after a successful ad injection.

Freshness & Cache

Env var Default Effect
SMALK_FRESHNESS_ENABLED true When true, the smalk:freshness command is auto-scheduled to run daily.
SMALK_CACHE_PURGER Smalk\Ads\Cache\NullCachePurger Fully-qualified class name of your CachePurger implementation. See Freshness & cache below.

Freshness & cache

Ad creatives rotate. To ensure visitors and crawlers always receive the latest ad, the package manages cache freshness through three complementary layers.

The smalk:freshness command

The package auto-schedules smalk:freshness to run once a day using Laravel's built-in scheduler (registered via callAfterResolving, so no manual $schedule->command(…) is needed). This command:

  1. Fetches your active-ad URLs from GET /api/v1/projects/{project_key}/ads/inventory/active-ad-urls/.
  2. Stores the path list in the application cache so the middleware can set Last-Modified and Cache-Control headers on those responses.
  3. Calls your configured CachePurger to clear full-page caches for those URLs.

Requirement: your server must run the Laravel task scheduler. Add this to your system crontab if it isn't already:

* * * * * cd /var/www/your-app && php artisan schedule:run >> /dev/null 2>&1

You can also run it manually at any time:

php artisan smalk:freshness

Three cache-clear layers

Layer A — Smalk-managed CDN purge (recommended, zero code)

Register your CDN credentials in the Smalk dashboard and Smalk will purge active-ad URLs nightly. No code changes on your side.

Supported providers: Cloudflare, CloudFront, Fastly, Akamai, KeyCDN.

Register credentials at: https://app.smalk.ai/workspaces/{workspace-id}/ads/brand-safety/cdn

Layer B — Application-level cache purge via CachePurger

If you use spatie/laravel-responsecache, point SMALK_CACHE_PURGER at the built-in adapter:

SMALK_CACHE_PURGER=Smalk\Ads\Cache\ResponseCachePurger

For any other full-page caching layer, implement the Smalk\Ads\Cache\CachePurger interface:

namespace App\Cache;

use Smalk\Ads\Cache\CachePurger;

class VarnishCachePurger implements CachePurger
{
    /** @param string[] $urls */
    public function purge(array $urls): void
    {
        foreach ($urls as $url) {
            // send a PURGE request to your Varnish node, call an SDK, etc.
        }
    }
}

Then wire it in .env:

SMALK_CACHE_PURGER=App\Cache\VarnishCachePurger

Layer C — Automatic Last-Modified + Cache-Control headers (always on)

After a successful freshness sweep, the middleware automatically sets:

Last-Modified: <UTC day boundary>
Cache-Control: public, max-age=21600

on every response for a URL in the active-ad list. This ensures downstream CDNs and browsers respect the 6-hour TTL cap and revalidate when the ad changes. No configuration needed.

Disabling pieces

All three concerns are independently toggleable. Only want the JS tracker?

SMALK_ADS_ENABLED=false
SMALK_TRACKING_ENABLED=false

Only want server-side ads and tracking, without the JS tracker (e.g. you add the <script> tag by hand in your layout)?

SMALK_JS_TRACKER_ENABLED=false

Shut everything off:

SMALK_JS_TRACKER_ENABLED=false
SMALK_ADS_ENABLED=false
SMALK_TRACKING_ENABLED=false

Manual middleware registration

The package appends SmalkMiddleware to the web group automatically on boot (using pushMiddlewareToGroup, which is stable across Laravel 10–12). This covers the vast majority of setups.

If you need to control the exact position of the middleware in the stack, you can also add it explicitly. In Laravel 11 / 12, in bootstrap/app.php:

->withMiddleware(function (Middleware $middleware) {
    $middleware->web(append: [\Smalk\Ads\Http\Middleware\SmalkMiddleware::class]);
})

In Laravel 10, in app/Http/Kernel.php, append it to the web group:

protected $middlewareGroups = [
    'web' => [
        // ... existing middleware ...
        \Smalk\Ads\Http\Middleware\SmalkMiddleware::class,
    ],
];

Note: there is currently no config flag to prevent auto-registration. If you add the middleware manually in a position that matters, bear in mind it will be registered twice. The middleware is idempotent (the ad fetch and tracking dispatch are both guarded by str_contains fast-paths and config checks), so duplicate registration is harmless — but you can open an issue if your setup requires explicit opt-out.

Verify

After deploying, confirm the ad is present in the server-rendered HTML by simulating a ChatGPT crawler:

curl -A "Mozilla/5.0 (compatible; ChatGPT-User/1.0)" https://your.site/article | grep -A2 smalk-ads

You should see the <div class="smalk-ads"> replaced with Smalk ad HTML. If you see the empty <div> instead, no active booking exists for that URL yet — the integration is working correctly.

GDPR

The JS tracker is bot-focused. It does not track human visitors, build profiles, set cookies, or store PII. Smalk has no human-analytics product.

The server-side tracking call forwards User-Agent and Referer only. IP forwarding (SMALK_TRACKING_FORWARD_IP) is off by default. Enabling it constitutes server-side processing of personal data; a Data Processing Agreement (DPA) is available — contact privacy@smalk.ai.

License

MIT

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 2
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-10

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固