jcergolj/metator-for-laravel
Metator for Laravel helps you manage SEO meta tags in your applications with a simple, fluent API. Define titles, descriptions, canonical URLs, and Open Graph tags per page or model, with sensible defaults and Blade-friendly output.
metator-for-laravel sits in the gap between "I can run php artisan serve locally" and "I have a real server with Deployer, PHP-FPM and a database." It scaffolds opinionated provisioning and deployment scripts into your application and gives you an Artisan entry point to drive them.
Minimal setup:
composer require --dev jcergolj/metator-for-laravel
php artisan metator:install
Then look at, in this order:
config/metator.php (publish it first if it isn't there) — this is where hosts, users, paths, PHP version and service capabilities live.scripts/ — the generated shell recipes, the Deployer recipe, and any .env.example scaffolding.deploy.php (or the generated Deployer entry point) — how the scripts get wired into dep deploy.Your first use case: take an app you already run locally and initialize a site on a fresh server. As of v9 the provisioner reads the application's own local .env as its source of truth — not scripts/.env.example — so a correct local .env is now a prerequisite, not a nice-to-have. Run the provisioning recipe once against a throwaway box before you point it at anything real.
Local-.env-as-template provisioning. The core workflow in v9 is: get the app working locally with values you actually understand, then let the provisioner derive production from it. Comments, ordering and multiline values (private keys, certificates, JSON blobs) survive the copy, so treat your local .env as a documented artifact rather than a scratchpad. Add a comment above anything non-obvious — it will be carried into the generated production env.
Expect production divergence, and lean into it. Provisioning intentionally rewrites a handful of things: it applies capability-based production defaults, generates a separate production APP_KEY, and writes site-owned database and Redis connection blocks. It also strips conflicting local values — DATABASE_URL, MariaDB socket paths, Redis credentials — including ones written as export FOO=bar, with stray whitespace, or assigned twice. The practical pattern is to keep your local .env about intent (which services you use) and let the provisioner own addresses and secrets.
Idempotent re-provisioning. Ordinary reruns preserve existing remote application values and credentials. That means provisioning belongs in your normal deploy/rebuild path, not just in a one-time setup ritual — you can re-run it to pick up a new capability flag or service without nuking the box's existing APP_KEY or database password.
Customize recipes, then re-scaffold deliberately. The recommended loop is: edit the generated recipes for your app (extra services, custom release hooks, non-standard PHP-FPM pool), and when a new package version ships, back up your customizations, run php artisan metator:install --force, and merge your changes back by hand. Do not treat --force as an upgrade command; it is a regeneration command. A common pattern is to keep your deltas in a small patch file or a dedicated deploy.local.php that you can re-apply mechanically.
Compose with Deployer rather than replacing it. The package generates Deployer tasks; keep your business logic in Deployer tasks and hooks, and let the package own the environment-shaping and server-bootstrap steps. Wire provisioning as a deploy:prepare-adjacent task so it only runs on new hosts, while the daily dep deploy stays a code-and-migrate operation.
Treat generated env as a deploy artifact. Since a production APP_KEY is generated separately from local, never copy a remote .env back down over your local one, and never check the generated file in. Anything you genuinely need to vary per site belongs in config/metator.php, not in ad-hoc edits to the output.
--force overwrites. Back up scripts/ and your Deployer recipe before upgrading to v9 and regenerating. There is no automatic three-way merge of your edits.scripts/.env.example is no longer the provisioner's input. If your existing workflow kept production secrets in a script-side example file, that data is now ignored. Move it into the local .env or into config before your first v9 deployment, and review application-specific service credentials explicitly — the release notes call this out as a manual step.=, export prefixes and duplicate keys are handled and deduplicated. If you were relying on a duplicate assignment to "win" (a common lazy way to override), that assumption is gone. Keep one assignment per key.DATABASE_URL, MariaDB socket paths and Redis credentials are removed from the production env on purpose, because they usually point at your laptop. If you do need a DATABASE_URL in production, add it after provisioning via a Deployer hook or your own task, and re-check it on the next run.bash -x to see exactly which values it derived from your .env. shellcheck scripts/*.sh locally catches most breakage before it reaches a host.--force workflow punishes.How can I help you explore Laravel packages today?