What it does
scriptor-simple-router lets you answer URLs that are not pages: a
/api/users/{id} JSON endpoint, a /webhook/stripe receiver,
anything request/response shaped. It runs ahead of Scriptor's page
resolver, so a matched route short-circuits the normal page flow; an
unmatched request falls through untouched.
Reach for it when you would otherwise be tempted to create a fake Page just to get a URL to execute code. It deliberately stays small: no middleware, no route groups, no per-route DI. If you need those, wrap FastRoute or league/route inside a plugin instead; the Cookbook has that recipe. This plugin is the floor, not the framework.
It is also the artefact built line by line across the Build a Module tutorial, so its source doubles as a teaching example of the activation pattern.
Install
Host install. Not on Packagist, so register the VCS repo, then require:
composer config repositories.scriptor-simple-router \
vcs https://github.com/bigin/scriptor-simple-router
composer require bigins/scriptor-simple-router:^0.1
Docker. Bake it in with the two build args:
services:
scriptor:
build:
args:
SCRIPTOR_PLUGIN_REPOS: "https://github.com/bigin/scriptor-simple-router"
SCRIPTOR_PLUGINS: "bigins/scriptor-simple-router:^0.1"
The plugin auto-registers via installed.json. Unlike a
page-resolving plugin, the router needs one activation line at the
top of your theme's _ext.php:
if (\Bigins\ScriptorSimpleRouter\Router::handle()) return;
Router::handle() returns true only when a route matched (it has
already sent the response); every other request returns false and
the theme builds as usual.
Configure
There is no plugins.* config block. Routes are code, declared in a
routes.php next to your theme's _ext.php:
use Bigins\ScriptorSimpleRouter\Request;
use Bigins\ScriptorSimpleRouter\Response;
use Bigins\ScriptorSimpleRouter\Router;
$router = Router::instance();
$router->get('/api/users/{id}', fn(Request $req) => Response::json([
'id' => (int) $req->param('id'),
]));
$router->post('/webhook/stripe', StripeWebhookController::class);
A handler is a Closure, a controller class string (invoked through
__invoke), or a [Class, method] array. Path parameters in
{braces} arrive via $req->param('name').
Use
The smallest end-to-end check: register the route above, add the
activation line to _ext.php, then:
curl -s http://localhost:8090/api/users/42
# {"id":42}
A request that matches no route (/about/, say) never reaches the
router's response path, so your normal pages keep working.
Links
- Source: https://github.com/bigin/scriptor-simple-router
- Version: v0.1.0 (not on Packagist; install via VCS repo)
- License: MIT
- Requires: Scriptor 2.1+ (Plugin API)
- Tutorial: Build a Module builds it from scratch; the routing cookbook recipes cover wrapping a fuller router.