Search by

gitsbt / waylume-sdk

omatsuman69

Waylume SDK for adding multi-page navigation guides to PHP applications.

v0.1.1 2026-08-14 12:53 UTC

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 flows
  • FlowRegistry: register and retrieve flows
  • LocaleResolver: resolve translated labels and instructions
  • WaylumeConfig: configure licensing, host, mode, and proof endpoint
  • LicenseProofSigner: create short-lived Ed25519 license proofs
  • WaylumeRenderer: 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.