Files
VITEC-website/packages/vitec/Classes/UserFunc/FaviconsJsonRenderer.php

48 lines
1.9 KiB
PHP
Executable File

<?php
declare(strict_types=1);
namespace Evomedien\Vitec\UserFunc;
use TYPO3\CMS\Core\Attribute\AsAllowedCallable;
/**
* Headless JSON renderer for the site-wide favicon / app-icon set.
*
* Emits a stable `favicons` object into every page response so the React
* frontend can render the <link>/<meta> head tags from the CMS instead of
* hard-coding them. The icon files live under public/fileadmin/icons/ and are
* referenced root-relative — identical convention to the image URLs emitted by
* UsecaseSerializer::image() (getImageUri also returns /fileadmin/... paths).
* If the frontend ever runs on a separate origin from the CMS, it must prefix
* these hrefs with the CMS base URL, exactly as it does for image URLs.
*
* Static by nature (same for every page) — no DB access, exception-free.
*/
final class FaviconsJsonRenderer
{
private const BASE = '/fileadmin/icons';
/** Browser UI / address-bar tint (VITEC navy). */
private const THEME_COLOR = '#26358C';
#[AsAllowedCallable]
public function render(string $content, array $conf): string
{
$payload = [
'themeColor' => self::THEME_COLOR,
'manifest' => self::BASE . '/site.webmanifest',
// Ready-to-render <link> descriptors, ordered most- to least-specific.
'links' => [
['rel' => 'icon', 'type' => 'image/x-icon', 'href' => self::BASE . '/favicon.ico'],
['rel' => 'icon', 'type' => 'image/png', 'sizes' => '32x32', 'href' => self::BASE . '/favicon-32.png'],
['rel' => 'icon', 'type' => 'image/png', 'sizes' => '16x16', 'href' => self::BASE . '/favicon-16.png'],
['rel' => 'apple-touch-icon', 'sizes' => '180x180', 'href' => self::BASE . '/apple-touch-icon.png'],
['rel' => 'manifest', 'href' => self::BASE . '/site.webmanifest'],
],
];
return json_encode($payload) ?: '';
}
}