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

Hosting Laravel Package

becklyn/hosting

Becklyn Hosting eases hosting integration for Symfony apps: configure tier, project, installation, and TrackJS; access HostingConfig; auto-inject uptime monitor comments into HTML; embed monitoring JS via Twig; and use the @hosting namespace.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first: becklyn/hosting is a Symfony bundle, not a Laravel package. You cannot composer require it into a Laravel app and use it directly without pulling in Symfony DI, HttpKernel, Twig, and Sentry internals. The realistic day-to-day leverage for a Laravel developer is conceptual porting — replicate its three core behaviors (tier-based config, uptime-comment injection, environment-gated monitoring script) as a small internal package or trait. Treat it as a reference implementation, not a dependency.

If you are working in a Symfony service alongside a Laravel one (multi-stack shop), the minimal setup is:

composer require becklyn/hosting

Then register the bundle in config/bundles.php and add the required config:

# config/packages/hosting.yaml
hosting:
    tier: '%env(APP_TIER)%'          # prod | staging | development
    project: 'my-project'
    installation: 'service-a-prod'
    trackjs: '%env(TRACKJS_TOKEN)%'  # optional

Where to look first:

  1. Becklyn\Hosting\Config\HostingConfig — the central read-only config object you'll inject everywhere.
  2. The MonitoringTokenListener — this is the mechanism that appends <!-- uptime monitor: {project} --> to every HTML response.
  3. The Twig extension providing hosting_embed_monitoring(), hosting_tier(), and hosting_embed_html_meta().

First use case: stop scattering if (env('APP_ENV') === 'production') checks across your codebase. Port the concept into a single config/hosting.php + a small HostingConfig wrapper so every feature flag, uptime hook, and monitoring script reads from one source.

Laravel-side port of the config:

// config/hosting.php
return [
    'tier'         => env('APP_TIER', 'development'),
    'project'      => env('HOSTING_PROJECT', 'my-project'),
    'installation' => env('HOSTING_INSTALLATION', 'local'),
    'trackjs'      => env('TRACKJS_TOKEN'),
];

Implementation Patterns

Pattern 1: Uptime monitoring via response middleware

Symfony does this in a kernel-response listener. In Laravel, replicate with terminable middleware:

// app/Http/Middleware/InjectUptimeMonitor.php
public function handle($request, Closure $next)
{
    $response = $next($request);

    if ($this->isHtml($response)) {
        $project = config('hosting.project');
        $html = $response->getContent();
        $response->setContent(
            str_replace('</body>', "<!-- uptime monitor: {$project} -->\n</body>", $html)
        );
    }

    return $response;
}

private function isHtml($response): bool
{
    return str_contains($response->headers->get('Content-Type', ''), 'text/html');
}

Register it globally so it runs last, mirroring the bundle's MonitoringTokenListener which is explicitly ordered after all other listeners. This is the single most reusable feature.

Pattern 2: Environment-gated monitoring script

The bundle exposes a Twig function and only excludes the development tier — staging gets monitoring too. Translate to a Blade directive:

// AppServiceProvider::boot()
Blade::directive('hosting_monitoring', function () {
    if (config('hosting.tier') === 'development') {
        return '';
    }
    $token = config('hosting.trackjs');
    if (blank($token)) {
        return '';
    }
    $jsonToken = json_encode($token);
    return "<script src=\"https://cdn.trackjs.com/agent/v3/latest/t.js\"></script>
             <script>window.TrackJS && TrackJS.install({ token: {$jsonToken} });</script>";
});

Use @hosting_monitoring in your layout — the same slot the Twig docs put hosting_embed_monitoring().

Pattern 3: Tier as a feature-flag source

The bundle's HostingConfig::isInDevelopmentTier() and hosting_tier() Twig helper exist precisely so you can gate functionality. In Laravel, wrap this in a Hosting facade so calling code reads naturally:

class Hosting
{
    public static function tier(): string { return config('hosting.tier'); }
    public static function is(string $tier): bool { return self::tier() === $tier; }
    public static function isProduction(): bool { return self::is('production'); }
}

Then feature-gate with @if(\App\Support\Hosting::isProduction()) in Blade, or Hosting::isProduction() guards in controllers. This is the highest-frequency day-to-day usage — it replaces ad-hoc env('APP_ENV') checks.

Pattern 4: Installation key for correlating deployments

The installation value is meant to be unique per deployment (only [a-z0-9-_]). Its stated purpose in the bundle is tokens and uptime monitoring. In practice, expose it as a response header or log context so you can correlate logs, Sentry events, and uptime pings to a specific stack:

$response->headers->set('X-Installation', config('hosting.installation'));

If you use Sentry on Laravel, tag the environment/host context the same way the bundle's Sentry integration associates errors with the right project and domain.

Pattern 5: Sentry exception filtering

Older releases of this bundle auto-ignore expected exceptions like CommandNotFoundException, NoMigrationsToExecute, RequestMatchException, and InternalRedirectException from Sentry. In Laravel, replicate via Sentry\before_send config:

'before_send' => function (\Sentry\Event $event, ?\Sentry\EventHint $hint) {
    $ignore = [
        \Symfony\Component\Console\Exception\CommandNotFoundException::class,
        \Doctrine\Migrations\Exception\NoMigrationsToExecute::class,
    ];
    if ($hint?->exception && in_array(get_class($hint->exception), $ignore, true)) {
        return null;
    }
    return $event;
},

Pattern 6: Twig helper equivalents (Blade)

Twig (Symfony) Blade (Laravel port)
hosting_tier() @hosting_tier or {{ config('hosting.tier') }}
hosting_embed_monitoring() @hosting_monitoring
hosting_embed_html_meta() @hosting_meta (custom directive rendering <meta> tags)
@hosting asset namespace Vite::asset() / @vite with a dedicated path

The @hosting asset namespace has no Laravel equivalent; just use a subfolder in resources/ and reference via Vite.

Gotchas and Tips

Config validation bites at boot, not runtime

The bundle validates tier against known values (production, staging, development) and rejects invalid ones at container compile time. If you port this, add a Validator or the check in a service provider — otherwise a typo'd APP_TIER=prod silently disables your monitoring script (which only excludes development, so it will still fire — a subtle mismatch). Decide explicitly which tiers should get the script; the bundle's rule is "everything except development," which surprises people who expect "only production."

Empty env vars for trackjs

There's a specific release (3.0.1) fixing "empty env vars for TrackJS token." In Laravel, env('TRACKJS_TOKEN') returns null for unset and '' for empty-string in .env — both should disable the script. Guard with blank() not is_null(), or you'll render an empty-token script tag in local dev.

tier with env vars needs proper resolution

Release 3.0.2 fixed "tier config with env vars." In Laravel this is a non-issue if you read config() inside a service or middleware, but do not read env() at runtime after php artisan config:cache — it returns null. Always go through config('hosting.tier').

Uptime comment ordering matters

MonitoringTokenListener is explicitly ordered to run last so all response content is finalized before the comment is injected. In Laravel, register your InjectUptimeMonitor after HandleCors and any middleware that rewrites HTML, and ensure it runs before compression. If you inject before ->render() or before a content-transforming middleware, the </body> you match on may not exist yet.

Skip non-HTML responses

The bundle explicitly skips BinaryFileResponse and handles missing Content-Type (fixes in 2.1.1). Port the same guards: check Content-Type and that it contains text/html before calling getContent(), or you'll corrupt file downloads and streamed responses.

SensioFrameworkExtraBundle quirk (Symfony only)

Release 3.3.1 only touches sensio_framework_extra.psr_message.enabled when sensio/framework-extra-bundle < 6.0. If you're on Symfony 5.x with that bundle at 6.0+, don't try forcing the option — it'll throw. Laravel developers can ignore this entirely.

Sentry SDK version pinning

Releases 3.2.1 / 3.2.2 exist solely because Sentry SDK upgrades broke exception filtering. If you're wiring Sentry manually in Laravel, pin sentry/sentry-laravel and re-run your before_send unit test after every minor bump — the EventHint and exception class surfaces have churned historically.

installation must be lowercase-safe and unique

The bundle documents it as a-z 0-9 -_. Generate it in CI from {project}-{env}-{git_sha} and validate with a regex before deploy. Using arbitrary strings (e.g., Service A/Prod) will break token generation and any downstream tooling that assumes the key format.

Maturity signals

Stars: 1, dependents: 0, last release 2026-06-09 but effectively dormant since the 3.3.x line. There is no community to unblock you and no Laravel bridge will ever exist. Fork the concepts, not the code — copy the listener pattern and the tier-gating rule into your own app/Support/Hosting and leave the Symfony bundle out of your composer.json unless you're genuinely running Symfony.

Extension points worth mimicking

  • Single read-only config object (HostingConfig) injected everywhere → in Laravel, a Hosting facade bound to a singleton. Keeps feature gates testable.
  • Response listener as the only HTML mutation point → one middleware, not scattered view composer hacks.
  • Twig function, not template variable — because the script needs to decision on tier at render time, not be passed in. Same argument applies to a Blade directive.
  • Auto-ignoring noisy exceptions in Sentry → a central before_send, so no one re-adds try/catch { ignore } blocks around migrations and console commands.
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.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator