# Page Zero Laravel Installation and Migration Guide

Updated: 2026-10-29. PHP 8.1+, Laravel 10/11/12; target: smking/laravel 0.23.2.
This is the shared installation guide used by the Dashboard and CLI. The CLI connects a site; your coding assistant installs and integrates the SDK.

## Before you start

Work on a development branch. Read composer.json, composer.lock, config/smking.php, existing SDK integration, deployment configuration and scheduled tasks.
Preserve existing data, routes, SEO, keys, settings and durable copies. Do not deploy, activate features or delete cached content without approval.
Package upgrades, switching to on_demand and enabling notifications are separate steps. Preserve the mode and notification settings of an existing on_demand installation.
Never put real secrets in commands, chat, logs or documentation. Values in angle brackets below must be replaced with settings supplied for the selected site.

## 1. Connect your site

From the project root, run the published CLI (0.10.0 or later):

```bash
pnpm dlx @soloworks/smking-wizard@latest connect
```

The CLI asks for your website's HTTPS origin. Enter the actual website you want to connect, not a Git repository URL or an example domain.
It then opens browser OAuth: sign in, select the matching workspace and site, and authorize the connection.
The CLI checks that the selected site's domain matches your input and asks for confirmation before writing local settings.
If you already know the correct origin, the optional --site-url argument supplies the same input instead of the prompt; it does not skip OAuth or confirmation.

SMKING_SAAS_URL selects the Page Zero backend; the default is https://getpagezero.com. Set it explicitly only when connecting to a different authorized backend.
The CLI does not install the SDK, change its configuration or delivery mode, configure scheduling, or store OAuth tokens in the project.
Without the CLI, obtain the settings for the same site from Page Zero. Do not generate a notification scope yourself or mix settings from different environments.

```dotenv
SMKING_API_KEY=<site publishable key>
SMKING_BASE_URL=<Page Zero origin for the selected environment>
SMKING_WEBHOOK_SECRET=<webhook secret for the same site>
```

## 2. Install or upgrade the SDK

Pin the version on your development branch and review the Composer diff:

```bash
composer require smking/laravel:0.23.2
```

Update only this package and required dependencies, not unrelated packages. Check the lockfile version and package source. Remove a repository override only if it was exclusively for an obsolete beta.
For a new installation, publish the configuration:

```bash
php artisan vendor:publish --tag=smking-config
```

If config/smking.php already exists, merge missing settings from the installed package while preserving project overrides. Do not use --force.
Laravel discovers the package automatically; do not register its provider or middleware twice. Preserve existing injection, CMS routes and SEO conflict handling.

If you use CMS, choose its mount path in SMKING_CMS_PATH and integrate with your existing routes and layout. Do not replace a working host controller or route.
Place <x-smking-runtime /> once in the relevant Blade layout's head. For a new CMS route, adapt this example to the chosen mount:

```php
// routes/web.php; use the configured CMS mount, not an assumed website path.
Route::get(rtrim(config('smking.cms.base_path'), '/') . '/{path?}', [\Smking\Laravel\Http\Controllers\CmsPageController::class, '__invoke'])
    ->where('path', '.*');
```

```blade
{{-- Integrate into the project's CMS view and existing layout. --}}
<x-smking-cms :slug="$slug" :page="$cms" />
```

### Render CMS metadata in the host layout

SDK 0.23.2+ uses the resolved CmsPage already rendered by the CMS component (or an existing smking::cms include) to normalize metadata in the document head. Set SMKING_CMS_PATH to the actual CMS mount. Only the matching public CMS path receives its page metadata; embedded CMS snippets do not replace another page's metadata.

The existing host layout can keep its metadata tags: the SDK replaces matching tags with the page's resolved editorial metadata and prevents duplicates. Manual metadata works even when automatic AEO generation is disabled or no AEO result exists. The page's manual/automatic metadata mode continues to control editorial ownership; neither switch is needed just to emit tags.

Open Graph and Twitter use the same existing title, description and image. Website name, locale and image alt text reuse existing HTML or JSON-LD facts. Image dimensions and MIME type are emitted only when known for that exact image; the SDK does not download or resize images, invent dimensions or create social accounts. No additional source GET, storage, background job or AI generation is added.

Deploy the reviewed SDK and rebuild Blade views with php artisan view:cache if view caching is used. Clearing a view cache alone does not deploy code. Verify the public HTML head and link previews after deployment; an external checker's aggregate score includes items outside metadata and is not an acceptance requirement.

If the project uses route:cache, explicitly include the required SDK route files in routes/web.php and rebuild routes through its normal deployment workflow:

```php
require base_path('vendor/smking/laravel/routes/webhook.php');
require base_path('vendor/smking/laravel/routes/preview.php');
require base_path('vendor/smking/laravel/routes/takeover.php');
```

The webhook is also needed for AEO notifications outside CMS. Resolve existing sitemap/llms.txt routes through the corresponding takeover settings or composition, not route replacement.
Use smking:publish-robots only when needed, preserving existing robots rules. Do not enable previously disabled features as a side effect of upgrading.
Load environment changes through the project's usual config:clear/config:cache workflow. Do not use cache:clear or delete durable copies to fix diagnostics.
Deploy the reviewed composer.lock with composer install; do not resolve new dependencies on the production host.

## 3. Prepare on_demand before first activation

Confirm with Page Zero that v2 reads, published snapshots, notifications and delivery infrastructure are ready for the selected site.
The customer's background commands do not prepare Page Zero's source snapshots. Do not copy Page Zero's private worker credentials into the customer project.

For a first migration, keep legacy mode while preparing and leave unverified notifications disabled:

```dotenv
SMKING_DELIVERY_MODE=legacy
SMKING_DELIVERY_LOCAL_STORE_PATH=<private absolute directory retained across deployments>
SMKING_DELIVERY_NOTIFICATIONS_ENABLED=false
SMKING_DELIVERY_NOTIFICATIONS_SCOPE=<64-character lowercase hexadecimal scope supplied by the same Page Zero source>
```

The default directory is storage/app/smking-delivery. If deployments replace release directories, use a shared private directory that survives releases, not public storage, an ordinary disposable cache or a temporary release directory.
Check permissions and disk space. PHP-FPM and background commands must use compatible PHP/configuration and have access to the same store.
No customer database migration or additional storage service is required. Do not copy an entire legacy Redis/cache store into this directory.

Before prewarming a first migration, load the reviewed configuration through the project's normal workflow. Using the same application directory, PHP and service account as the background commands, initialize and check their local health while still in legacy:

```bash
php artisan smking:delivery:work --prepare
php artisan smking:delivery:report --prepare
php artisan smking:delivery:work --status
php artisan smking:delivery:report --status
```

Both heartbeats must be recent and there must be no unresolved work/report errors or losses; prewarm rejects unavailable background health with background_unavailable. Repeat preparation if a long preparation session outlives the health interval, checking errors rather than clearing state. These commands do not start a scheduler or prove continuing execution. Preserve the health and scheduling of an existing on_demand installation.

Obtain a complete current release plan from Page Zero for the site's enabled resources, including withdrawals. Do not infer completeness from an old index or CDN responses.
The plan is a private local JSON file containing source identity, a key fingerprint and bounded targets with their published revisions, not the raw key.
Set RELEASE_PLAN to the absolute filename supplied for your site. Prewarm in batches using each response's next_offset:

```bash
php artisan smking:delivery:prewarm --plan="$RELEASE_PLAN" --offset=0
# Continue with the returned next_offset; inspect each batch's errors and revisions.
php artisan smking:delivery:prewarm --plan="$RELEASE_PLAN" --check
```

Per-resource prewarming can help diagnosis but does not replace the complete release plan. Use only real resource identifiers from the selected site's plan.
A first v1 migration has no v2 copies to import: prewarm from the current source.
Only installations with an older v2 cache should consider explicit import and reconcile --import-index. Stop old writers and preserve a baseline first; do not guess identifiers by scanning cache entries.
For an existing 0.23 on_demand installation, preserve its directory, mode, scope and notification settings.

## 4. Configure background execution

The SDK and CLI do not install cron or systemd. Configure these commands in your host's existing scheduling system, once per minute, using the application's PHP, working directory and service account:

```bash
php artisan schedule:run --no-interaction
php artisan smking:delivery:work
php artisan smking:delivery:report
```

Reuse an existing Laravel scheduler rather than adding a duplicate. Use your host's normal overlap prevention and log rotation; no particular host or service manager is assumed.
For a first migration, prepare the host configuration while in legacy but start normal work/report ticks when on_demand is activated; their ordinary ticks require that mode. Do not disable or duplicate the application's existing scheduler. The --prepare checks above are the legacy preparation path, not a substitute for starting and observing the continuing ticks after activation.
These are CLI processes, not three guaranteed HTTP requests per minute or PHP-FPM requests. An empty work queue does not download content; report performs bounded reporting/heartbeat work.
The scheduler performs daily reconciliation of known content, not a full-site download every minute. New content still requires source publication and notification or explicit prewarming.

## 5. Verify, then activate separately

```bash
php artisan smking:doctor --json
php artisan smking:delivery:work --status
php artisan smking:delivery:report --status
php artisan smking:delivery:reconcile --status
```

A passing doctor or prewarm check is not authorization to activate. Verify complete source revisions, prewarming, work/report health, retry state, webhook reachability, signatures/scope, and actual content delivery.
Confirm notification resources with Page Zero; Laravel supports aeo,cms-page,markdown,site-file. Do not edit source records manually as an installation step.
Only after testing and explicit deployment/activation approval, set SMKING_DELIVERY_MODE=on_demand and enable verified notifications.
Preserve the source, keys, mounts, service account and durable directory; load configuration through the normal deployment workflow.

Choose representative routes from this project, not a fixed example path. Test AEO on an existing non-CMS page, preserving its original content, canonical, title and description; check a single JSON-LD output and the configured summary/FAQ.
If CMS is enabled, test its mount root, articles and nested paths. Inspect the actual public HTML head: exactly one title, description and canonical, with the expected article-specific Open Graph and Twitter values. Verify manual metadata both with and without generated AEO, and separately validate JSON-LD when present. A successful publish or an updated CMS API response alone does not prove that the host template renders the metadata. Test enabled Markdown, sitemap and llms.txt resources, updates, withdrawals and recovery.
Public requests read durable local copies. Authorized smking_preview draft requests are a live-read exception and must not write public copies.
During a source outage, preserve valid prior copies. Corrupt copies must fail safely; explicit prewarming restores them. Keep test content and evidence available for inspection.

## 6. Monitor and roll back safely

Observe source content reads separately from event reporting, background queue health, daily reconciliation, delivery errors and withdrawal revisions.
Where available, compare page p95/p99 latency and PHP-FPM active workers, listen queue and max children reached over the same interval. CLI background costs are separate from PHP-FPM costs.
No browser-side SaaS content request does not mean zero background traffic. Do not claim capacity improvements or CDN hits without measurement.
Roll back using a reviewed deployment and settings while preserving durable copies and withdrawal records. Do not blindly downgrade to a package that cannot interpret withdrawals, delete copies, or force legacy mode.
