PHPackages                             blackcube/ssr - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. blackcube/ssr

ActiveLibrary[HTTP &amp; Networking](/categories/http)

blackcube/ssr
=============

Server-side routing and rendering bridge for blackcube/dcore

1.0.0(1mo ago)08↓55.6%BSD-3-ClausePHPPHP ^8.1

Since Apr 4Pushed 2mo agoCompare

[ Source](https://github.com/blackcubeio/ssr)[ Packagist](https://packagist.org/packages/blackcube/ssr)[ Docs](https://github.com/blackcubeio/ssr)[ RSS](/packages/blackcube-ssr/feed)WikiDiscussions devel Synced 1mo ago

READMEChangelogDependencies (21)Versions (3)Used By (0)

Blackcube SSR
=============

[](#blackcube-ssr)

Server-side routing for dcore. Maps slugs to PHP handlers, injects SEO metadata, handles errors.

[![License](https://camo.githubusercontent.com/6cb285b57819f8de0acfb34923298f4f569f962544e8fe35331da2d163f4e485/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4253442d2d332d2d436c617573652d626c75652e737667)](LICENSE.md)[![Packagist Version](https://camo.githubusercontent.com/499c02e2486f5054c07c852c966339b613afe08d44fda8d9283e5f2b11492197/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f626c61636b637562652f7373722e737667)](https://packagist.org/packages/blackcube/ssr)

Installation
------------

[](#installation)

```
composer require blackcube/ssr
```

Requirements
------------

[](#requirements)

- [blackcube/dcore](https://github.com/blackcubeio/dcore) — data layer (Content, Tag, Slug, Xeo)
- PSR-7 (`psr/http-message`) and PSR-15 (`psr/http-server-middleware`)

How it works
------------

[](#how-it-works)

1. **RoutingMiddleware** matches the request URL against dcore slugs
2. **HandlerRegistry** resolves the slug's route to a handler class
3. The handler receives `Content`, `Tag`, `Slug` automatically via DI
4. **XeoInjection** pushes SEO meta tags into the Yii3 view layer

```
Request → RoutingMiddleware → HandlerDescriptor → Handler(Content, Tag, …) → Response

```

Registering handlers
--------------------

[](#registering-handlers)

### Via PHP attributes

[](#via-php-attributes)

```
use Blackcube\Ssr\Attributes\RoutingHandler;
use Psr\Http\Server\RequestHandlerInterface;

#[RoutingHandler(route: 'page')]
final class PageHandler implements RequestHandlerInterface
{
    public function __construct(
        private readonly Content $content,
        private readonly WebViewRenderer $viewRenderer,
    ) {}

    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        return $this->viewRenderer->render('page', ['content' => $this->content]);
    }
}
```

Enable attribute scanning in params:

```
'blackcube/ssr' => [
    'scanAttributes' => true,
    'scanAliases' => ['@app/Handlers'],
],
```

### Via config

[](#via-config)

```
'blackcube/ssr' => [
    'configHandlers' => [
        'page' => App\Handlers\PageHandler::class,           // __invoke or RequestHandlerInterface
        'article' => [App\Handlers\Blog::class, 'article'],  // Class::method
    ],
],
```

Handler modes
-------------

[](#handler-modes)

The registry analyzes handler signatures and dispatches accordingly:

ModeDetectionInjection`construct`Implements `RequestHandlerInterface`CMS objects injected via constructor`invoke`Has `__invoke()`CMS objects injected via method params`method``[Class, 'method']` configCMS objects injected via method paramsCMS types tracked: `Content`, `Tag`, `Slug`, `Element`, `Content|Tag` unions.

SEO injection (Xeo)
-------------------

[](#seo-injection-xeo)

Enable automatic SEO meta injection:

```
// In your middleware pipeline
RoutingMiddleware::withXeo()
```

Requires `yiisoft/yii-view-renderer` and `yiisoft/html` (both in `suggest`).

XeoInjection reads the Xeo attached to the slug and injects:

TagSource```noindex` / `nofollow```Xeo title``Xeo description``Open Graph (title, description, image, type)``Twitter Card``Canonical slugJSON-LD data is available via `XeoInjection::getJsonLds()`. An optional transformer callback allows reshaping the data:

```
RoutingMiddleware::withXeo(function (array $jsonLds): array {
    // Add @context, reshape FAQ, etc.
    return $jsonLds;
})
```

Error handling
--------------

[](#error-handling)

### Error handler attribute

[](#error-handler-attribute)

```
use Blackcube\Ssr\Attributes\RoutingErrorHandler;

#[RoutingErrorHandler(route: 'error-404', code: 404)]
final class NotFoundHandler { /* ... */ }

#[RoutingErrorHandler(route: 'error-5xx', min: 500, max: 599)]
final class ServerErrorHandler { /* ... */ }
```

### Error handler config

[](#error-handler-config)

```
'configErrorHandlers' => [
    'error-404' => ['handler' => App\Handlers\NotFound::class, 'code' => 404],
    'error-5xx' => ['handler' => App\Handlers\ServerError::class, 'min' => 500, 'max' => 599],
],
```

### Error dispatch chain

[](#error-dispatch-chain)

- **SsrFallbackHandler** — replaces default 404 handler, dispatches to CMS error handler
- **SsrThrowableResponseFactory** — catches exceptions, resolves status code, dispatches to CMS error handler or falls back to Yii3 default

Preview
-------

[](#preview)

**PreviewContext** bridges the dcore preview system with HTTP. Reads the JWT from cookie and preview state from session, enabling content preview with simulated dates.

Configuration
-------------

[](#configuration)

```
// config/params.php
return [
    'blackcube/ssr' => [
        'scanAttributes' => false,         // scan for #[RoutingHandler] attributes
        'scanAliases' => [],               // aliases to scan (e.g. '@app/Handlers')
        'configHandlers' => [],            // route => handler class or [class, method]
        'configErrorHandlers' => [],       // route => error handler config
    ],
];
```

Let's be honest
---------------

[](#lets-be-honest)

**This is slug-based routing, not a router.**

SSR does not replace your router. It intercepts requests that match dcore slugs and dispatches them to CMS handlers. Everything else passes through to the normal pipeline.

**Tight coupling with dcore.**

SSR depends on dcore's `Slug`, `Content`, `Tag`, `HandlerDescriptor`, `Xeo`. It is the rendering bridge for the Blackcube stack, not a standalone routing library. The core is PSR-7/PSR-15 — Yii3 view renderer is optional (in `suggest`).

License
-------

[](#license)

BSD-3-Clause. See [LICENSE.md](LICENSE.md).

Author
------

[](#author)

Philippe Gaultier

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance88

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

44d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/545714?v=4)[pgaultier](/maintainers/pgaultier)[@pgaultier](https://github.com/pgaultier)

---

Top Contributors

[![pgaultier](https://avatars.githubusercontent.com/u/545714?v=4)](https://github.com/pgaultier "pgaultier (3 commits)")

---

Tags

psr-7slugroutingpsr-15cmsseoserver-side-rendering

###  Code Quality

TestsCodeception

### Embed Badge

![Health badge](/badges/blackcube-ssr/health.svg)

```
[![Health](https://phpackages.com/badges/blackcube-ssr/health.svg)](https://phpackages.com/packages/blackcube-ssr)
```

###  Alternatives

[league/route

Fast routing and dispatch component including PSR-15 middleware, built on top of FastRoute.

6633.1M115](/packages/league-route)[mezzio/mezzio

PSR-15 Middleware Microframework

3883.6M97](/packages/mezzio-mezzio)[tuupola/slim-basic-auth

PSR-7 and PSR-15 HTTP Basic Authentication Middleware

4442.0M26](/packages/tuupola-slim-basic-auth)[relay/relay

A PSR-15 server request handler.

3302.1M86](/packages/relay-relay)[tuupola/cors-middleware

PSR-7 and PSR-15 CORS middleware

1331.8M24](/packages/tuupola-cors-middleware)[laminas/laminas-stratigility

PSR-7 middleware foundation for building and dispatching middleware pipelines

586.6M81](/packages/laminas-laminas-stratigility)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
