gitsbt / waylume-sdk
Waylume SDK for adding multi-page navigation guides to PHP applications.
Requires
- php: >=8.1
- ext-json: *
- ext-sodium: *
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-14 13:20:39 UTC
README
Add multi-page Waylume navigation guides to PHP-rendered websites, including Laravel, Symfony, WordPress, and plain PHP applications.
Requirements
- PHP 8.1 or newer
- JSON and Sodium extensions
- A Waylume site license for production use
Install
composer require gitsbt/waylume-sdk
Local development without credentials
On localhost, 127.0.0.1, and the IPv6 loopback address, no Waylume license,
credentials, proof endpoint, or local Waylume server is required. Use
SdkMode::Auto with an internet connection.
Credentials and the proof endpoint in the next two sections are required only when the site is viewed on a non-local hostname.
1. Configure production credentials
Store the credentials issued in the Waylume dashboard on your server. Never expose the private key in HTML or browser JavaScript.
WAYLUME_PUBLIC_KEY_ID=wlm_sdk_pub_xxxxxxxxxxxxxxxx WAYLUME_PRIVATE_KEY=M... # Base64 PKCS#8 body copied from the dashboard
The dashboard exports private_key as the Base64 body only, without
-----BEGIN PRIVATE KEY----- / -----END PRIVATE KEY----- lines. Pass that
value directly to LicenseProofSigner; do not add PEM markers. The environment
variable names shown here are examples and may be changed to match your app.
2. Add a production proof endpoint
Create a server-side POST endpoint such as /api/waylume-proof:
<?php use Waylume\Sdk\License\LicenseProofSigner; require __DIR__ . '/../vendor/autoload.php'; header('Content-Type: application/json'); $input = json_decode(file_get_contents('php://input'), true) ?? []; $requestedHostname = LicenseProofSigner::normalizeHostname((string) ($input['hostname'] ?? '')); // Read this fixed value from your application's trusted configuration. // Never derive it from the request body or the HTTP Host header. $allowedHostname = 'app.example.com'; if ($requestedHostname === '' || $requestedHostname !== $allowedHostname) { http_response_code(403); echo json_encode(['error' => 'Hostname is not allowed.']); exit; } $signer = LicenseProofSigner::fromPrivateKey((string) getenv('WAYLUME_PRIVATE_KEY')); echo $signer->sign($allowedHostname)->toJson();
Replace app.example.com with the licensed hostname stored in your existing
application configuration. Do not accept an arbitrary hostname supplied by the
browser.
3. Mark guide targets
<a data-waylume="upgrade-btn" href="/login">Upgrade to Pro</a> <button data-waylume="google-login-btn">Continue with Google</button>
The data-waylume value must match the flow step's target.
4. Define and register flows
use Waylume\Sdk\Flow\FlowRegistry; $registry = new FlowRegistry(); $registry->register([ 'id' => 'upgrade-to-pro', 'label' => 'Upgrade to Pro', 'steps' => [ [ 'id' => 'upgrade-btn', 'summary' => 'Start the upgrade', 'instruction' => 'Click Upgrade to Pro.', 'target' => 'upgrade-btn', 'actionType' => 'click', 'waitFor' => 'navigation', 'expectedUrlPattern' => '/', ], ], ]);
Flows can also be loaded from JSON:
$registry->registerJson(file_get_contents(__DIR__ . '/waylume/upgrade-flow.json'));
5. Publish the browser loader
Copy the packaged browser loader to a public directory during deployment.
use Waylume\Sdk\Rendering\WaylumeRenderer; copy( WaylumeRenderer::runtimeAssetPath(), __DIR__ . '/public/vendor/waylume/loader.js' );
6. Render the bootstrap
Render the bootstrap on every page that participates in a guide:
use Waylume\Sdk\Rendering\WaylumeRenderer; use Waylume\Sdk\Sdk\SdkMode; use Waylume\Sdk\Sdk\WaylumeConfig; $config = new WaylumeConfig( publicKeyId: getenv('WAYLUME_PUBLIC_KEY_ID') ?: null, mode: SdkMode::Auto, proofEndpoint: '/api/waylume-proof', ); $renderer = new WaylumeRenderer( registry: $registry, config: $config, runtimeSrc: '/vendor/waylume/loader.js', );
Place this before </body> in your shared layout:
<?= $renderer->bootstrapScript() ?>
7. Add a launcher or navigation trigger
Launcher listing every registered flow:
<?= $renderer->launcher( children: '<button aria-label="Open guides">?</button>', locale: 'en', floating: true, position: 'bottom-right', ) ?>
Trigger for one specific flow:
<?= $renderer->navigation( flowId: 'upgrade-to-pro', children: '<button>Start guide</button>', locale: 'en', ) ?>
Pass only trusted markup to children; it is intentionally not escaped.
Multi-page flows
Set expectedUrlPattern on the first step and on steps that wait for
navigation. Only same-site paths beginning with / are accepted. Render the
bootstrap in the shared layout so the guide can resume after a full page load.
For Inertia, Livewire, or another client-side router, call this after a route change:
window.Waylume?.scheduleAutoResume();
Main APIs
FlowFactory: define and validate flowsFlowRegistry: register and retrieve flowsLocaleResolver: resolve translated labels and instructionsWaylumeConfig: configure licensing, host, mode, and proof endpointLicenseProofSigner: create short-lived Ed25519 license proofsWaylumeRenderer: render the bootstrap, launcher, and navigation trigger
The browser emits waylume:step-change, waylume:flow-complete, and
waylume:flow-skip events.
License
Production use requires a Waylume site license. See LICENSE and waylume.app.