diff --git a/composer.json b/composer.json
index 1ad60aa..4d1a7a4 100644
--- a/composer.json
+++ b/composer.json
@@ -20,6 +20,7 @@
"ep/ep-theme": "@dev",
"fluidtypo3/vhs": "^8.0",
"georgringer/news": "^14.1",
+ "lochmueller/staticfilecache": "^15.2",
"ssch/typo3-encore": "^7.0",
"typo3/cms-backend": "^13.4",
"typo3/cms-belog": "^13.4",
diff --git a/composer.lock b/composer.lock
index edb338a..dc703e4 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "85a0f79761fbcaf517b130c2f7a3e114",
+ "content-hash": "f1134476988f3bf5d2a3a74092cdb285",
"packages": [
{
"name": "b13/container",
@@ -1785,6 +1785,94 @@
],
"time": "2022-02-21T08:41:21+00:00"
},
+ {
+ "name": "lochmueller/staticfilecache",
+ "version": "15.2.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/lochmueller/staticfilecache.git",
+ "reference": "21697e6b3ea3584995fefe9ab74615927a872744"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/lochmueller/staticfilecache/zipball/21697e6b3ea3584995fefe9ab74615927a872744",
+ "reference": "21697e6b3ea3584995fefe9ab74615927a872744",
+ "shasum": ""
+ },
+ "require": {
+ "ext-pdo": "*",
+ "ext-zlib": "*",
+ "php": "^8.1",
+ "typo3/cms-backend": "^12.4||^13.4",
+ "typo3/cms-core": "^12.4||^13.4",
+ "typo3/cms-extensionmanager": "^12.4||^13.4"
+ },
+ "require-dev": {
+ "andersundsehr/phpstan-git-files": "^1.0",
+ "friendsofphp/php-cs-fixer": "^3.30",
+ "phpstan/extension-installer": "^1.3",
+ "phpstan/phpstan": "^1.10",
+ "saschaegerer/phpstan-typo3": "^1.8",
+ "ssch/typo3-rector": "^2.2",
+ "typo3/testing-framework": "^8.0"
+ },
+ "suggest": {
+ "friendsofsymfony/http-cache": "For HTTP proxy cache services like Varnish",
+ "lochmueller/seocli": "Scan websites against SEO criteria and/or trigger the indexing process and cache warming in deployment scripts"
+ },
+ "type": "typo3-cms-extension",
+ "extra": {
+ "typo3/cms": {
+ "web-dir": ".Build/Web",
+ "extension-key": "staticfilecache",
+ "cms-package-dir": "{$vendor-dir}/typo3/cms"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "SFC\\Staticfilecache\\": "Classes"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "GPL-2.0-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Tim Lochmüller",
+ "email": "tim@fruit-lab.de",
+ "homepage": "https://github.com/lochmueller",
+ "role": "Developer"
+ }
+ ],
+ "description": "Transparent static file cache solution using mod_rewrite and mod_expires. Increase performance for static pages by a factor of 230!!",
+ "homepage": "https://extensions.typo3.org/extension/staticfilecache",
+ "keywords": [
+ "StaticFileCache",
+ "TYPO3 CMS",
+ "cache",
+ "file",
+ "magic",
+ "speed",
+ "static"
+ ],
+ "support": {
+ "docs": "https://docs.typo3.org/p/lochmueller/staticfilecache/main/en-us/",
+ "issues": "https://github.com/lochmueller/staticfilecache/issues",
+ "source": "https://github.com/lochmueller/staticfilecache"
+ },
+ "funding": [
+ {
+ "url": "https://paypal.me/lochmueller",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/lochmueller",
+ "type": "github"
+ }
+ ],
+ "time": "2025-09-02T19:26:27+00:00"
+ },
{
"name": "lolli42/finediff",
"version": "1.1.2",
diff --git a/config/system/settings.php b/config/system/settings.php
index d7c0b03..edb2349 100644
--- a/config/system/settings.php
+++ b/config/system/settings.php
@@ -97,6 +97,44 @@ return [
'scheduler' => [
'maxLifetime' => '1440',
],
+ 'staticfilecache' => [
+ 'backendDisplayMode' => 'both',
+ 'boostMode' => '0',
+ 'clearCacheForAllDomains' => '1',
+ 'cspGenerationOverride' => '0',
+ 'debugHeaders' => '0',
+ 'disableInDevelopment' => '0',
+ 'enableGeneratorBrotli' => '0',
+ 'enableGeneratorGzip' => '1',
+ 'enableGeneratorPhp' => '0',
+ 'enableGeneratorPlain' => '0',
+ 'hashUriInCache' => '0',
+ 'headerSizeBuffer' => '1.5',
+ 'htaccessTemplateName' => 'EXT:staticfilecache/Resources/Private/Templates/Htaccess.html',
+ 'inlineAssetsFileSize' => '50000',
+ 'inlineScriptMinify' => '0',
+ 'inlineServiceFavIcon' => '0',
+ 'inlineServiceScripts' => '0',
+ 'inlineServiceStyles' => '0',
+ 'inlineStyleAssets' => 'ico,png,woff2',
+ 'inlineStyleMinify' => '0',
+ 'largeIdentifierInCacheTable' => '0',
+ 'maxHeaderSize' => '8192',
+ 'overrideCacheDirectory' => '',
+ 'overrideClientUserAgent' => '',
+ 'phpTemplateName' => 'EXT:staticfilecache/Resources/Private/Templates/Php.html',
+ 'rawurldecodeCacheFileName' => '0',
+ 'renameTablesToOtherPrefix' => '0',
+ 'sendCacheControlHeaderRedirectAfterCacheTimeout' => '1',
+ 'sendHttp2PushEnable' => '0',
+ 'sendHttp2PushFileExtensions' => 'css,js',
+ 'sendHttp2PushFileLimit' => '10',
+ 'sendHttp2PushLimitToArea' => '',
+ 'useFallbackMiddleware' => '1',
+ 'useReverseUriLengthInPriority' => '1',
+ 'validFallbackHeaders' => 'Content-Type,Content-Language,Content-Security-Policy,Link',
+ 'validHtaccessHeaders' => 'Content-Type,Content-Language,Content-Security-Policy,Link',
+ ],
],
'FE' => [
'cacheHash' => [
diff --git a/public/.htaccess b/public/.htaccess
index 0427542..f133c6f 100644
--- a/public/.htaccess
+++ b/public/.htaccess
@@ -412,6 +412,111 @@ AddDefaultCharset utf-8
# NOTE: Add your additional local storages here
RewriteRule ^(?:fileadmin/|typo3conf/|typo3temp/|uploads/) - [L]
+ ### Begin: StaticFileCache (preparation) ####
+
+ # Document root configuration
+ RewriteRule .* - [E=SFC_ROOT:%{DOCUMENT_ROOT}]
+
+ # Cleanup URI
+ RewriteCond %{REQUEST_URI} ^.*$
+ RewriteRule .* - [E=SFC_URI:/%{REQUEST_URI}]
+ RewriteCond %{REQUEST_URI} ^/.*$
+ RewriteRule .* - [E=SFC_URI:%{REQUEST_URI}]
+ RewriteCond %{REQUEST_URI} ^/?$
+ RewriteRule .* - [E=SFC_URI:/]
+
+ # Cleanup HOST
+ RewriteCond %{HTTP_HOST} ^([^:]+)(:[0-9]+)?$
+ RewriteRule .* - [E=SFC_HOST:%1]
+
+ # Get scheme
+ RewriteRule .* - [E=SFC_PROTOCOL:http]
+ RewriteCond %{SERVER_PORT} ^443$ [OR]
+ RewriteCond %{HTTP:X-Forwarded-Proto} https
+ RewriteRule .* - [E=SFC_PROTOCOL:https]
+
+ # Get port
+ RewriteRule .* - [E=SFC_PORT:80]
+ RewriteCond %{ENV:SFC_PROTOCOL} ^https$ [NC]
+ RewriteRule .* - [E=SFC_PORT:443]
+ RewriteCond %{SERVER_PORT} ^[0-9]+$
+ RewriteRule .* - [E=SFC_PORT:%{SERVER_PORT}]
+ RewriteCond %{HTTP:X-Forwarded-Port} ^[0-9]+$
+ RewriteRule .* - [E=SFC_PORT:%{HTTP:X-Forwarded-Port}]
+
+ # Full path for redirect
+ RewriteRule .* - [E=SFC_FULLPATH:typo3temp/assets/tx_staticfilecache/%{ENV:SFC_PROTOCOL}_%{ENV:SFC_HOST}_%{ENV:SFC_PORT}%{ENV:SFC_URI}/index]
+
+ # Extension (Order: br, gzip, default)
+ RewriteRule .* - [E=SFC_EXT:]
+ RewriteCond %{HTTP:Accept-Encoding} br [NC]
+ RewriteRule .* - [E=SFC_EXT:.br]
+ RewriteCond %{ENV:SFC_ROOT}/%{ENV:SFC_FULLPATH}%{ENV:SFC_EXT} !-f
+ RewriteRule .* - [E=SFC_EXT:]
+ RewriteCond %{ENV:SFC_EXT} ^$
+ RewriteCond %{HTTP:Accept-Encoding} gzip [NC]
+ RewriteRule .* - [E=SFC_EXT:.gz]
+ RewriteCond %{ENV:SFC_EXT} ^\.gz$
+ RewriteCond %{ENV:SFC_ROOT}/%{ENV:SFC_FULLPATH}%{ENV:SFC_EXT} !-f
+ RewriteRule .* - [E=SFC_EXT:]
+
+ # Write Extension to SFC_FULLPATH
+ RewriteRule .* - [E=SFC_FULLPATH:%{ENV:SFC_FULLPATH}%{ENV:SFC_EXT}]
+
+ ### Begin: StaticFileCache (main) ####
+
+ # We only redirect URI's without query strings
+ RewriteCond %{QUERY_STRING} ^$
+
+ # It only makes sense to do the other checks if a static file actually exists.
+ RewriteCond %{ENV:SFC_ROOT}/%{ENV:SFC_FULLPATH} -f
+
+ # NO frontend or backend user is logged in. Logged in users may see different
+ # information than anonymous users. But the anonymous version is cached. So
+ # don't show the anonymous version to logged in users.
+ RewriteCond %{HTTP_COOKIE} !staticfilecache [NC]
+
+ # Avoid cached versions for workspace preview links of users that are not logged in
+ RewriteCond %{HTTP_COOKIE} !ADMCMD_prev [NC]
+
+ # We only redirect GET requests
+ RewriteCond %{REQUEST_METHOD} GET
+
+ # Rewrite the request to the static file.
+ RewriteRule .* %{ENV:SFC_ROOT}/%{ENV:SFC_FULLPATH} [L]
+
+ # Do not allow direct call the cache entries
+ RewriteCond %{ENV:SFC_URI} ^/typo3temp/assets/tx_staticfilecache/.*
+ RewriteCond %{ENV:REDIRECT_STATUS} ^$
+ RewriteRule .* - [F,L]
+
+ ### Begin: StaticFileCache (options) ####
+
+ # Set proper content type and encoding for compressed html.
+
+ SetEnv no-gzip 1
+ SetEnv no-brotli 1
+
+ Header set Content-Encoding gzip
+
+ ForceType text/html
+
+
+ SetEnv no-gzip 1
+ SetEnv no-brotli 1
+
+ Header set Content-Encoding br
+
+ ForceType text/html
+
+
+ # Avoid .br files being delivered with Content-Language: br headers
+
+ RemoveLanguage .br
+
+
+ ### End: StaticFileCache ###
+
# If the file/symlink/directory does not exist but is below /typo3/, redirect to the main TYPO3 entry point.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^typo3/(.*)$ %{ENV:CWD}index.php [QSA,L]