htaccess file

This is the base .htaccess configuration. Please take a look for the default variables (SFC_ROOT, SFC_GZIP) and read the comments carefully.

  ### Begin: StaticFileCache (preparation) ####

  # Document root configuration
  RewriteRule .* - [E=SFC_ROOT:%{DOCUMENT_ROOT}]
  # RewriteRule .* - [E=SFC_ROOT:%{DOCUMENT_ROOT}/t3site] # Example if your installation is installed in a directory
  # NOTE: There are cases (apache versions and configuration) where DOCUMENT_ROOT do not exists. Please set the SFC_ROOT to the right directory without DOCUMENT_ROOT then!

  # 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]

  # Disable cache for EXT:solr indexing requests
  RewriteCond %{HTTP:X-Tx-Solr-Iq} .+
  RewriteRule .* - [E=SFC_HOST:invalid-host]

# Disable cache for EXT:crawler indexing requests
RewriteCond %{HTTP:X-T3Crawler} .+
RewriteRule .* - [E=SFC_HOST:invalid-host]

  # Important Note for scheme and port. TYPO3 handle Reverse proxies by respect
  # X-Forwarded-For headers. The Apache do not know this configuration. If there
  # is a reverse proxy that e.g. terminate SSL and all requests are "http", please
  # Adapt the following lines to force "http".

  # 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, php, 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:]
  RewriteCond %{ENV:SFC_EXT} ^$
  RewriteRule .* - [E=SFC_EXT:.php]
  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: https://github.com/lochmueller/staticfilecache/issues/395
  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]

  # Handle application cache
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-l
  RewriteRule ^.*\.sfc$ %{ENV:CWD}index.php?eID=sfc_manifest [QSA,L]

  ### Begin: StaticFileCache (options) ####

  # Set proper content type and encoding for gzipped html.
  <FilesMatch "\.gzip$">
     SetEnv no-gzip 1
     SetEnv no-brotli 1
     <IfModule mod_headers.c>
        Header set Content-Encoding gzip
     </IfModule>
  </FilesMatch>
  <FilesMatch "\.gz$">
     SetEnv no-gzip 1
     SetEnv no-brotli 1
     <IfModule mod_headers.c>
        Header set Content-Encoding gzip
     </IfModule>
  </FilesMatch>
  <FilesMatch "\.br$">
     SetEnv no-gzip 1
     SetEnv no-brotli 1
     <IfModule mod_headers.c>
        Header set Content-Encoding br
     </IfModule>
  </FilesMatch>

  # if there are same problems with ForceType, please try the AddType alternative
  # Set proper content type gzipped html
  <FilesMatch "\.gzip$">
     ForceType text/html
     # AddType "text/html" .gzip
  </FilesMatch>
  <FilesMatch "\.js\.gzip$">
     ForceType text/javascript
     # AddType "text/javascript" .gzip
  </FilesMatch>
  <FilesMatch "\.js\.gz$">
     ForceType text/javascript
     # AddType "text/javascript" .gzip
  </FilesMatch>
  <FilesMatch "\.css\.gzip$">
     ForceType text/css
     # AddType "text/css" .gzip
  </FilesMatch>
  <FilesMatch "\.css\.gz$">
     ForceType text/css
     # AddType "text/css" .gzip
  </FilesMatch>
  <FilesMatch "\.xml\.gzip$">
     ForceType text/xml
     # AddType "text/xml" .gzip
  </FilesMatch>
  <FilesMatch "\.rss\.gzip$">
     ForceType text/xml
     # AddType "text/xml" .gzip
  </FilesMatch>
  <FilesMatch "\.gz$">
     ForceType text/html
     # AddType "text/html" .gz
  </FilesMatch>
  <FilesMatch "\.js\.gz$">
   ForceType text/javascript
   # AddType "text/javascript" .gz
  </FilesMatch>
  <FilesMatch "\.css\.gz$">
   ForceType text/css
   # AddType "text/css" .gz
  </FilesMatch>
  <FilesMatch "\.xml\.gz$">
     ForceType text/xml
     # AddType "text/xml" .gz
  </FilesMatch>
  <FilesMatch "\.rss\.gz$">
     ForceType text/xml
     # AddType "text/xml" .gz
  </FilesMatch>
  <FilesMatch "\.br$">
     ForceType text/html
     # AddType "text/html" .br
  </FilesMatch>
  <FilesMatch "\.xml\.br$">
     ForceType text/xml
     # AddType "text/xml" .br
  </FilesMatch>
  <FilesMatch "\.rss\.br$">
     ForceType text/xml
     # AddType "text/xml" .br
  </FilesMatch>

  # Avoid .br files being delivered with Content-Language: br headers
  <IfModule mod_mime.c>
     RemoveLanguage .br
  </IfModule>

  ### End: StaticFileCache ###
Copied!

If you use the default .htaccess rewrite rules that come with the TYPO3 dummy, then the relevant StaticFileCache configuration should be inserted in the .htaccess file just before these lines:

# If the file/symlink/directory does not exist => Redirect to index.php.
# For httpd.conf, you need to prefix each '%{REQUEST_FILENAME}' with '%{DOCUMENT_ROOT}'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^.*$ %{ENV:CWD}index.php [QSA,L]
Copied!

If the TYPO3 Installation isn´t in your root directory (say your site lives in https://some.domain.com/t3site/), then you have to add the '/t3site' part to the configuration snippet. It must be placed right after %{DOCUMENT_ROOT}. Here is the line of the ruleset to illustrate:

RewriteRule .* - [E=SFC_ROOT:%{DOCUMENT_ROOT}/t3site]
Copied!

You are of course free to make the rules as complex as you like.

There might be some files you never want to pull from cache even if they are indexed. For example you might have some custom speaking url rules that make your RSS feed accessible as rss.xml. You can skip rewriting to static file with the following condition:

RewriteCond %{REQUEST_FILENAME} !^.*\.xml$
Copied!

Keep in mind: If you are using the gzip feature of StaticFileCache you have to take care, that the output is not encoded twice. If the result of the page are cryptic chars like "�‹��í[krÛH’þ-Eô�ª¹±-¹[ À—�É${dùÙkÙ�[îé..." remove the "text/html " in the mod_deflate section of the default TYPO3 .htaccess rules.

Troubleshooting: It is also necessary that the autogenerated .htaccess files in the StaticFileCache directory (by default typo3temp/assets/tx_staticfilecache) will be not ignored by the server. Sometimes in the vHost configuration various directories could be marked to deny an overwrite by an additional .htaccess file for performance reasons.