SCSS/JS compilation breaks on TYPO3 v14 for any page.includeCSS/page.includeJS entry pointing at fileadmin/... (or other FAL-resolved, non-EXT: paths)
Environment
- bk2k/bootstrap-package: 16.0.0
- typo3/cms-core: v14.3.4
- PHP: 8.4
Summary
On TYPO3 v14, any .scss/.less file referenced in page.includeCSS (or .js in page.includeJS) via a fileadmin-relative path fails to compile with:
ScssPhp\ScssPhp\Exception\CompilerException: .../public/FAL:1:/templates/demo/theme.scss
file not found for @import: FAL:1:/templates/demo/theme.scss on line 1, at column 0
EXT:-relative paths (e.g. EXT:bootstrap_package/Resources/Public/Scss/bootstrap5/theme.scss) are unaffected — only paths resolved through TYPO3's file abstraction layer break.
Root cause
In TYPO3 v14, TYPO3\CMS\Frontend\Http\RequestHandler::generatePageContent() no longer passes plain path strings into PageRenderer::addCssFile()/addJsFile(). It now wraps every page.includeCSS/page.includeJS value in a SystemResourceInterface via:
$cssResource = $this->systemResourceFactory->createResource($cssResource);
(vendor/typo3/cms-frontend/Classes/Http/RequestHandler.php, includeCSS handling around line 446)
For anything that isn't an EXT: reference (e.g. a fileadmin/... path), the resultntation used as the PageRenderer cssFiles array key becomes a FAL "combinedidentifier" of the form:
FAL:: e.g. FAL:1:/templates/demo/theme.scss.
BK2K\BootstrapPackage\Hooks\PageRenderer\PreProcessHook::execute() (Classes/Hooksphp:42) takes that array key literally and passes it straight toCompileService::getCompiledFile(), which calls GeneralUtility::getFileAbsFileName($file). That function has no notion of the FAL: notation, so it just prepends the public path to the literal string, producing a bogus path like /var/www/html/public/FAL:1:/templates/demo/thesn't exist, hence the CompilerException.
This affects the extension's own documented usage pattern of per-site/per-mandanteadmin/ (not just custom setups) — any TYPO3 v14 site using a fileadmin-basedtheme.scss convention hits this immediately.
Suggested fix
Resolve the FAL: identifier back to a real filesystem path via ResourceFactory before handing it to CompileService, in PreProcessHook::execute(). Patch attached below — verified against a TYPO3
v14.3.4 + bootstrap-package 16.0.0 site using a fileadmin/templates/{mandant}/theme.scss convention succeeds and the compiled CSS is correct. EXT:-relative entries are untouched since they never start with FAL:.
Patch
--- a/Classes/Hooks/PageRenderer/PreProcessHook.php
+++ b/Classes/Hooks/PageRenderer/PreProcessHook.php
@@ -12,6 +12,7 @@
use BK2K\BootstrapPackage\Service\CompileService;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Http\ApplicationType;
+use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
@@ -39,7 +40,8 @@
$files = [];
if (is_array($params[$key])) {
foreach ($params[$key] as $file => $settings) {
-
$compiledFile = $this->getCompileService()->getCompiledFile($GLOBALS['TYPO3_REQUEST'], $file);
-
$resolvedFile = $this->resolveFalIdentifier($file);
-
$compiledFile = $this->getCompileService()->getCompiledFile($GLOBALS['TYPO3_REQUEST'], $resolvedFile);
if ($compiledFile !== null) {
$settings['file'] = $compiledFile;
$files[$compiledFile] = $settings;
@@ -53,6 +55,33 @@
}
-
* TYPO3 >= 14 wraps page.includeCSS/includeJS values that point at fileadmin (or
-
* other non-EXT:) files in a SystemResource object before this hook ever se
-
* the array key we receive is then its string representation, e.g.
-
* "FAL:1:/templates/demo/theme.scss", which GeneralUtility::getFileAbsFileN
-
* cannot resolve. Resolve it back to a real filesystem path via FAL so the SCSS
-
* compiler can find the file. EXT:-relative values are untouched (unaffecte
-
-
-
-
- protected function resolveFalIdentifier(string $file): string
- {
-
if (str_starts_with($file, 'FAL:')) {
-
-
$fileObject = GeneralUtility::makeInstance(ResourceFactory::class)
-
->getFileObjectFromCombinedIdentifier(substr($file, 4));
-
if ($fileObject !== null) {
-
return $fileObject->getForLocalProcessing(false);
-
-
-
// fall through and let the caller deal with the original value
-
-
-
- }
- /**
- Get the compile service
- @return CompileService
SCSS/JS compilation breaks on TYPO3 v14 for any page.includeCSS/page.includeJS entry pointing at fileadmin/... (or other FAL-resolved, non-EXT: paths)
Environment
Summary
On TYPO3 v14, any .scss/.less file referenced in page.includeCSS (or .js in page.includeJS) via a fileadmin-relative path fails to compile with:
ScssPhp\ScssPhp\Exception\CompilerException:
.../public/FAL:1:/templates/demo/theme.scssfile not found for @import: FAL:1:/templates/demo/theme.scss on line 1, at column 0
EXT:-relative paths (e.g. EXT:bootstrap_package/Resources/Public/Scss/bootstrap5/theme.scss) are unaffected — only paths resolved through TYPO3's file abstraction layer break.
Root cause
In TYPO3 v14, TYPO3\CMS\Frontend\Http\RequestHandler::generatePageContent() no longer passes plain path strings into PageRenderer::addCssFile()/addJsFile(). It now wraps every page.includeCSS/page.includeJS value in a SystemResourceInterface via:
$cssResource = $this->systemResourceFactory->createResource($cssResource);
(vendor/typo3/cms-frontend/Classes/Http/RequestHandler.php, includeCSS handling around line 446)
For anything that isn't an EXT: reference (e.g. a fileadmin/... path), the resultntation used as the PageRenderer cssFiles array key becomes a FAL "combinedidentifier" of the form:
FAL:: e.g. FAL:1:/templates/demo/theme.scss.
BK2K\BootstrapPackage\Hooks\PageRenderer\PreProcessHook::execute() (Classes/Hooksphp:42) takes that array key literally and passes it straight toCompileService::getCompiledFile(), which calls GeneralUtility::getFileAbsFileName($file). That function has no notion of the FAL: notation, so it just prepends the public path to the literal string, producing a bogus path like /var/www/html/public/FAL:1:/templates/demo/thesn't exist, hence the CompilerException.
This affects the extension's own documented usage pattern of per-site/per-mandanteadmin/ (not just custom setups) — any TYPO3 v14 site using a fileadmin-basedtheme.scss convention hits this immediately.
Suggested fix
Resolve the FAL: identifier back to a real filesystem path via ResourceFactory before handing it to CompileService, in PreProcessHook::execute(). Patch attached below — verified against a TYPO3
v14.3.4 + bootstrap-package 16.0.0 site using a fileadmin/templates/{mandant}/theme.scss convention succeeds and the compiled CSS is correct. EXT:-relative entries are untouched since they never start with FAL:.
Patch
--- a/Classes/Hooks/PageRenderer/PreProcessHook.php
+++ b/Classes/Hooks/PageRenderer/PreProcessHook.php
@@ -12,6 +12,7 @@
use BK2K\BootstrapPackage\Service\CompileService;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Http\ApplicationType;
+use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
@@ -39,7 +40,8 @@
$files = [];
if (is_array($params[$key])) {
foreach ($params[$key] as $file => $settings) {
@@ -53,6 +55,33 @@
}