The Ultimate TypoScript Conditions Cheatsheet

Improve your TYPO3 website's functionality with modern TypoScript conditions! Learn guidelines and examples with this easy-to-use cheat sheet .

The Ultimate TypoScript Conditions Cheatsheet

Modern TypoScript conditions help you write cleaner, safer, and more maintainable TYPO3 configuration. This guide is built as a practical cheatsheet, focused on real-world examples using Symfony Expression Language for fast copy-paste and immediate use.

Modern TypoScript conditions help you write cleaner, safer, and more maintainable TYPO3 configuration. This guide is built as a practical cheatsheet, focused on real-world examples using Symfony Expression Language for fast copy-paste and immediate use.

Since TYPO3 v9.4 LTS, Symfony Expression Language powers modern TypoScript conditions and replaces legacy syntax. If you work with TYPO3 daily, you already know how critical conditions are for controlling rendering, environments, and behavior across projects.

Instead of theory, this guide focuses on how modern TypoScript conditions actually work, including variables, functions, custom conditions, and common pitfalls. 

In this guide, we will walk through everything you need to use TypoScript conditions correctly, confidently, and upgrade-safe.

Use CaseTypoScript ConditionContext
Check site language ID[siteLanguage("languageId") == 1]FE
Check site language title[siteLanguage("title") == "English"]FE
Check page UID[page["uid"] == 17]FE
Check multiple pages[page["uid"] in [17,24]]FE
Check page backend layout[page["backend_layout"] == 1]FE
Check root page[tree.level == 0]FE
Check if page is in rootline[2 in tree.rootLineIds]FE
Check frontend user logged in[frontend.user.isLoggedIn]FE
Check backend user logged in[backend.user.isLoggedIn]BE
Check backend admin user[backend.user.isAdmin]BE
Check application context[applicationContext == "Development"]FE / BE
Check production environment[applicationContext matches "#^Production#"]FE / BE
Check TYPO3 version[compatVersion("11.5")]FE / BE
Check domain / host[like(request.getNormalizedParams().getHttpHost(), "*.example.com")]FE
Check HTTPS[request.getNormalizedParams().isHttps()]FE
Check query parameter[request.getQueryParams()['foo'] == 1]FE
Check current weekday[date("w") == 5]FE
Check site identifier[site("identifier") == "mysite"]FE
Check workspace[workspace.isLive]FE / BE
Check frontend user group[usergroup("12")]FE

Symfony Expression Language–based TypoScript conditions are the modern, supported way to write conditions in TYPO3. They replace legacy condition syntax and are stable across current LTS versions.

TYPO3 Versions That Support Symfony TypoScript Conditions

TYPO3 VersionSupportNotes
TYPO3 8 LTSNoLegacy TypoScript conditions only
TYPO3 9.0–9.3NoSymfony Expression Language not available
TYPO3 9.4 LTSYesFirst release with modern conditions
TYPO3 10 LTSYesFully stable
TYPO3 11 LTSYesRecommended for production
TYPO3 12 LTSYesCurrent best practice

Deprecated vs Recommended Condition Syntax

  • Legacy conditions ([globalVar], [userFunc]) are deprecated
  • Symfony-based conditions are:
    • Forward-compatible
    • Upgrade-safe
    • Actively maintained

Use only Symfony Expression Language for new and updated projects.

Migration & Upgrade Guidance

  • TYPO3 ≤ 8
    Upgrade required before using modern conditions
  • TYPO3 9.0–9.3
    Refactor conditions before upgrading
  • TYPO3 ≥ 9.4
    Use Symfony-based conditions exclusively

Enterprise Best Practices

  • Assume TYPO3 ≥ 9.4 as the baseline.
  • Validate conditions during upgrades to:
  • Never mix legacy and modern condition syntaxes

TYPO3 integrates selected Symfony components to strengthen its core architecture without adding unnecessary complexity.

  • The components, such as Console, Routing, YAML, PropertyAccess, and ExpressionLanguage, are deeply embedded in the TYPO3 Core and designed for long-term stability.
  • Symfony Expression Language provides a compact, readable way to evaluate logical expressions that return a value, most commonly booleans.
  • TYPO3 uses this component to power modern TypoScript conditions, replacing fragmented legacy syntax with a unified expression model.
  • Since TYPO3 v9.4 LTS, Symfony Expression Language is the foundation for TypoScript conditions in both Frontend and Backend contexts.

Condition logic is exposed through variables and functions, enabling cleaner configuration, easier extension, and fully upgrade-safe custom conditions aligned with TYPO3’s long-term roadmap.

TYPO3 replaced legacy TypoScript conditions with Symfony Expression Language to introduce a unified, extensible, and future-proof syntax.

Below is a direct before - after comparison, showing how common conditions translate from legacy syntax to modern TYPO3 (≥ 9.4).

Condition Syntax Structure

TYPO3 ≤ 9.3 (Legacy)

Conditions were evaluated individually and chained together.

  • [condition1] && [condition2]

TYPO3 ≥ 9.4 (Symfony-based)

Conditions are evaluated as a single expression.

  • [condition1 && condition2]

Language Detection

Legacy

  • [globalVar = GP:L = 1]

Modern

  • [siteLanguage("languageId") == 1]
  • [siteLanguage("title") == "English"]
  • [siteLanguage("locale") == "en_US.UTF-8"]

TypoScript Constants

Legacy

  • [globalVar = LIT:1 = {$myConstant}]

Modern

  • [{$myConstant} == 1]

Page UID Checks

Legacy

  • [globalVar = TSFE:id = 17]
  • [globalVar = TSFE:id = 17, TSFE:id = 24]

Modern

  • [page["uid"] == 17]
  • [page["uid"] in [17,24]]
  • [getTSFE().id == 17]
  • [getTSFE().id in [17,24]]

Page Properties

Legacy

  • [page|backend_layout = 1]

Modern

  • [page["backend_layout"] == 1]

Domain / Hostname Checks

Legacy

  • [globalString = IENV:HTTP_HOST = *.example.com]

Modern

  • [like(request.getNormalizedParams().getHttpHost(),"*.example.com")]

Date-Based Conditions

Legacy

  • [dayofweek = 5]

Modern

  • [date("w") == 5]

Extension / Request Parameters

Legacy

  • [globalVar = GP:tx_extkey|param > 0]

Modern

  • [(request.getQueryParams()['tx_extkey'])['param'] > 0]

Why the New Syntax Is Better

  • One unified expression language
  • Cleaner, more readable conditions
  • Supports complex logic (&&, ||, in, regex)
  • Enables custom TypoScript conditions
  • Consistent behavior across Frontend and Backend

Modern TypoScript conditions expose variables and functions through Symfony Expression Language. Both are used inside condition expressions, but they serve different purposes.

Variables

Variables represent available runtime data and are used for direct comparisons.

Characteristics

  • Read-only
  • No arguments
  • Context-dependent (FE / BE)

Typical use cases

  • Page properties
  • Language information
  • User state
  • Application context
  • Site configuration

Example:

 

[page["uid"] == 1]

 

Functions

Functions encapsulate logic or processing and may accept parameters.

Characteristics

  • Callable expressions
  • Accept arguments
  • Can return dynamic values

Typical use cases

  • Request inspection
  • Date evaluation
  • Pattern matching
  • Version checks
  • Environment logic

Example:

 

[date("w") == 5]

 

Use variables for simple checks and functions for dynamic or computed conditions. The sections below are grouped accordingly.

Why This Distinction Matters

  • Prevents misuse of conditions
  • Improves readability in complex setups
  • Helps structure custom condition providers
  • Makes debugging faster

TYPO3 provides a set of built-in variables that can be used directly in modern TypoScript conditions. These variables expose runtime information and are evaluated using Symfony Expression Language.

Each variable below represents a data source, not executable logic.

applicationContext - Application Environment

Returns the current TYPO3 application context as a string.

Common use cases

  • Environment-based configuration
  • Feature toggles per stage (Dev / Staging / Live)
[applicationContext == "Development"]
[applicationContext matches "#^Development#"]
[applicationContext matches "#^Production/Dev#"]
[applicationContext matches "#^Production/(Dev|Staging)#"]
[applicationContext matches "#^Production/Live#"]
[applicationContext == "Production/Live/ClusterServer1"]
[applicationContext matches "#^Production/Live#" && getTSFE().isBackendUserLoggedIn()]
[not (applicationContext matches "#Production#")]

 

page - Page Properties

Provides access to the current page record as an array.

Common use cases

  • Page-based rendering logic
  • Template or layout switching
[page["pid"] == 2]
[page["uid"] == 17]
[page["backend_layout"] == 1]

 

TypoScript Constants - {$foo.bar}

All TypoScript constants are available inside conditions. Be mindful of data types when comparing values.

 

[{$foo.bar} == 4711]
["{$foo.bar}" == "4711"]

 

tree - Page Tree Information

Provides access to page tree and rootline data.

Common use cases

  • Root page detection
  • Section-based configuration
[tree.level == 0]
[tree.rootLine[0]["uid"] == 1]
[2 in tree.rootLineIds]

 

backend - Backend User Context (BE Only)

Exposes backend user information. Available only in Backend context.

 

[backend.user.isAdmin]
[backend.user.isLoggedIn]
[backend.user.userId == 5]
[like("," ~ backend.user.userGroupList ~ ",", ",1,")]

 

frontend - Frontend User Context (FE Only)

Exposes frontend user authentication data. Available only in Frontend context.

 

[frontend.user.isLoggedIn]
[frontend.user.userId == 5]
[like("," ~ frontend.user.userGroupList ~ ",", ",1,")]

 

typo3 - TYPO3 Environment Information

Provides TYPO3 system-level metadata.

 

[typo3.version == "10.4.2"]
[typo3.branch == "10.4"]
[typo3.devIpMask == "192.168.0.100"]

 

workspace - TYPO3 Workspace Context

Exposes workspace-related information. Primarily used in Backend context.

 

[workspace.workspaceId == 1]
[workspace.isLive]
[workspace.isOffline]

 

Important Notes

  • Variables are read-only
  • Availability depends on execution context (FE / BE)
  • Prefer variables for simple, deterministic checks

Frontend-only conditions are evaluated during Frontend rendering and depend on an active HTTP request and an initialized TSFE (TypoScript Frontend Controller).

If evaluated in Backend, CLI, or Scheduler, these conditions will always resolve to false.

FE Context & Evaluation Lifecycle

Frontend conditions are available:

  • After site resolution
  • After language resolution
  • During page rendering

They rely on:

  • Active request object
  • Resolved site and language
  • Initialized TSFE instance

Frontend User & Authentication Conditions

Used to evaluate frontend user state and permissions.

 

[frontend.user.isLoggedIn]
[frontend.user.userId == 5]
[usergroup("12")]
[loginUser("*")]
[loginUser("3,7,9")]

 

Notes

  • usergroup() and loginUser() evaluate FE users only
  • Anonymous users always return false

Frontend Page & TSFE-Based Conditions

These conditions rely directly on the TSFE object.

 

[getTSFE().page["uid"] == 1]
[getTSFE().id in [17,24]]
[getTSFE().isBackendUserLoggedIn()]

 

Notes

  • getTSFE() is Frontend-only
  • Always evaluates to false in BE or CLI

Frontend Request-Based Conditions

Used to evaluate request data, headers, and routing arguments.

 

[request.getQueryParams()['foo'] == 1]
[request.getParsedBody()['foo'] == 1]
[request.getHeaders()['Accept'] == 'json']
[request.getCookieParams()['foo'] == 1]
[request.getPageArguments().get('foo_id') > 0]
[request.getNormalizedParams().isHttps()]
[request.getNormalizedParams().getHttpHost() == "t3planet.com"]

 

Notes

  • Request data is unavailable in CLI
  • Use only during FE rendering

Frontend Site & Language Conditions

Available only after site configuration is resolved.

 

[site("identifier") == "t3terminal"]
[site("base").getHost() == "t3planet.com"]
[site("rootPageId") == 1]
[siteLanguage("languageId") == 0]
[siteLanguage("locale") == "de_CH"]
[siteLanguage("title") == "German"]

 

Notes

  • site() and siteLanguage() may return null
  • Safe only in FE context

Frontend Session Conditions

Used to read values from the TYPO3 FE session.

 

[session("session:foo|bar") == 1234567]

 

Notes

  • Requires an active FE session
  • Not available in BE or CLI

Backend-only conditions are evaluated inside TYPO3 Backend context, where TSFE does not exist.

They depend on:

  • Authenticated backend user
  • Backend request context
  • Workspace configuration

Backend User & Permission Conditions

Used to control backend-specific TypoScript logic.

 

[backend.user.isLoggedIn]
[backend.user.isAdmin]
[backend.user.userId == 5]
[backend.user.userGroupList matches "/,1,/"]

 

Notes

  • backend.user is undefined in FE
  • Permission checks are BE-only

Backend Workspace Conditions

Used to differentiate live and non-live workspaces.

 

[workspace.isLive]
[workspace.workspaceId == 1]

 

Notes

  • Workspace context exists only in BE
  • FE rendering always assumes live workspace

These functions are context-agnostic but depend on available runtime data.

 

[date("d.m.") == "05.04.2019"]
[date("j") == 7]

[like("foobarbaz", "*bar*")]
[like("fooBarBaz", "/f[o]{2,2}[aBrz]+/")]

[traverse(request.getQueryParams(), 'tx_news_pi1/news') > 0]

[ip("172.18.*")]
[ip("devIP")]

[compatVersion("11.5")]
[getenv("VIRTUAL_HOST") == "t3planet.de"]

Most TypoScript condition issues fail silently. The following problems account for the majority of real-world bugs.

1. getTSFE() Always Returns false

What happens

Conditions using getTSFE() never match.

Why it happens

  • Condition is evaluated in Backend, CLI, or Scheduler context
  • TSFE is not initialized

How to avoid

  • Use getTSFE() only in Frontend rendering
  • Never rely on it in Backend logic

2. Frontend vs Backend Context Confusion

What happens

Conditions always evaluate to false.

Why it happens

  • frontend.* used in Backend
  • backend.* used in Frontend

How to avoid

  • Keep FE and BE conditions in separate blocks
  • Never mix contexts in the same condition

3. site() or  siteLanguage() Returns null

What happens

Language or site-based conditions do not match.

Why it happens

  • Site configuration not resolved
  • Condition evaluated too early or in CLI

How to avoid

  • Use site-related conditions only in FE
  • Always assume null is possible

4. Type Mismatch (String vs Integer)

What happens

Condition looks correct but never matches.

Why it happens

  • Comparing "1" with 1
  • TypoScript constants evaluated as strings

How to avoid

  • Match data types explicitly
  • Be careful with quoted constants

5. Request Data Not Available

What happens

Request-based conditions fail unexpectedly.

Why it happens

  • Condition evaluated in CLI or BE
  • No HTTP request exists

How to avoid

  • Use request.* only in FE
  • Avoid during cache warmup or builds

TypoScript conditions are powerful, but they are configuration tools, not a place for business logic. Using them correctly improves performance, upgrade safety, and long-term maintainability.

Best Practices for TypoScript Conditions

Use TypoScript conditions when you need to control configuration, not application behavior.

Recommended usage

  • Enable or disable features
  • Switch templates or assets
  • Apply environment-specific configuration
  • Control rendering based on page, site, or language

Guidelines

  • Prefer deterministic checks (page, site, applicationContext)
  • Keep expressions short and readable
  • Separate Frontend and Backend conditions clearly
  • Revalidate all conditions during TYPO3 upgrades (11 LTS, 12 LTS)

Anti-Patterns: When NOT to Use TypoScript Conditions

Avoid TypoScript conditions when logic becomes dynamic, complex, or data-dependent.

Do not use conditions for

  • Business rules or workflows
  • Complex decision trees
  • User-specific personalization logic
  • Performance-critical runtime decisions
  • External API or service calls

Better alternatives

RequirementRecommended Solution
Business logicPHP services
PersonalizationControllers / ViewHelpers
Runtime decisionsMiddleware
Feature togglesConfiguration or feature flags
Heavy logicCached configuration

Rule of thumb

If a condition:

  • Is hard to read
  • Needs comments to explain
  • Depends on runtime data

It probably does not belong in TypoScript.

One of the biggest advantages of modern TypoScript conditions is the ability to define custom conditions. Unlike legacy userFunc–based conditions, Symfony Expression Language allows clean, reusable, and upgrade-safe extensions.

Legacy vs Modern Approach (Quick Context)

TYPO3 ≤ 9.3 (Legacy)

 

[userFunc = \Vendor\Extension\UserFunc\MyUserFunc('foo')]

 

TYPO3 ≥ 9.4 (Modern)

 

[variableA === 'valueB']

 

Modern conditions are:

  • Declarative
  • Readable
  • Fully integrated into TYPO3 Core

Step 1: Register the Expression Language Provider

Register your custom provider inside the extension configuration.

File: Configuration/ExpressionLanguage.php

 

<?php
return [
'typoscript' => [
\Vendor\ExtensionName\ExpressionLanguage\CustomTypoScriptConditionProvider::class,
]
];

 

This makes your variables or functions available to TypoScript conditions.

Step 2: Implement the Custom Condition Provider

Create a provider that exposes variables to the expression language.

File: Classes/ExpressionLanguage/CustomTypoScriptConditionProvider.php

 

<?php

namespace Vendor\ExtensionName\ExpressionLanguage;

use TYPO3\CMS\Core\ExpressionLanguage\AbstractProvider;

class CustomTypoScriptConditionProvider extends AbstractProvider
{
public function __construct()
{
$this->expressionLanguageVariables = [
'variableA' => 'valueB',
];
}
}

 

Key points

  • Variables are read-only
  • Values should be deterministic
  • Avoid runtime-heavy logic here

Step 3: Use the Custom Condition in TypoScript

Once registered, the variable can be used like any built-in condition.

 

[variableA === 'valueB']
page >
page = PAGE
page.10 = TEXT
page.10.value = Matched
[GLOBAL]

 

The condition is evaluated using Symfony Expression Language and behaves consistently across TYPO3 versions.

Best Practices for Custom Conditions

  • Use custom conditions for configuration decisions only
  • Keep logic simple and predictable
  • Avoid database queries, API calls, or user-specific data
  • Always re-test custom providers during TYPO3 upgrades

Why This Approach Is Preferred

  • No deprecated APIs
  • Fully compatible with TYPO3 11 & 12
  • Cleaner than userFunc
  • Easier to maintain in enterprise projects

TYPO3 also allows you to register custom expression functions, not just variables. This is an advanced technique and should be used only when simple variables are not sufficient.

This approach is suitable for:

  • Reusable condition logic
  • Read-only lookups
  • Controlled external checks (with caution)

When to Use a Custom Expression Function

Use a custom function when:

  • A condition needs parameters
  • Logic cannot be expressed as a static variable
  • The result can be treated as configuration data

Do not use this for:

  • Business logic
  • User-specific decisions
  • Performance-critical rendering paths

Step 1: Implement an Expression Function Provider

Create a provider that registers a custom function for TypoScript conditions.

 

<?php

namespace Vendor\ExtensionName\TypoScript;

use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class CustomConditionFunctionsProvider implements ExpressionFunctionProviderInterface
{
public function getFunctions(): array
{
return [
$this->getWebserviceFunction(),
];
}

protected function getWebserviceFunction(): ExpressionFunction
{
return new ExpressionFunction(
'webservice',
function () {
// Compiler not required for TypoScript usage
},
function ($existingVariables, string $endpoint, int $uid) {
return GeneralUtility::getUrl(
'https://t3planet.de/en/endpoint/' . $endpoint . '/' . $uid
);
}
);
}
}

 

Important notes

  • Only the evaluator is used for TypoScript
  • Return values must be predictable
  • Avoid slow or unstable endpoints

Step 2: Use the Custom Function in TypoScript

Once registered, the function behaves like a native condition function.

 

[webservice('pages', 10)]
page.10 >
page.10 = TEXT
page.10.value = Matched
[GLOBAL]

 

You can also compare the returned value explicitly.

 

[webservice('pages', 10) === 'Expected title']
page.10 >
page.10 = TEXT
page.10.value = Matched
[GLOBAL]

 

Key Warnings (Read This Before Using)

  • Conditions are evaluated frequently
  • External requests can slow down rendering
  • Failures may silently break conditions

Best practice

  • Cache results aggressively
  • Keep functions side-effect free
  • Prefer static variables whenever possible

Why This Is an Advanced Pattern

  • Powerful but easy to misuse
  • Requires strong control over performance
  • Best suited for enterprise projects with strict guidelines

If a condition becomes hard to reason about, it likely belongs in:

  • PHP services
  • Controllers
  • Middleware

Modern TypoScript conditions based on Symfony Expression Language are the recommended and future-safe approach for configuring TYPO3 projects. They offer cleaner syntax, better readability, and a consistent evaluation model across Frontend and Backend.

If you’re maintaining existing TYPO3 sites, migrating legacy conditions to modern syntax should be part of every upgrade strategy. This reduces technical debt, prevents silent failures, and keeps your configuration aligned with current TYPO3 standards.

Use TypoScript conditions where they make sense, for configuration, not business logic, and always validate them during major TYPO3 upgrades. With the right structure and discipline, modern conditions become a powerful and reliable tool in everyday TYPO3 development.

Modern TypoScript conditions use Symfony Expression Language (introduced in TYPO3 v9.4) to evaluate logic in a single, readable expression. They replace legacy condition syntax and are upgrade-safe.

Legacy conditions like [globalVar] and [userFunc] are deprecated. They may still work in older TYPO3 versions, but should not be used in new projects or upgrades.

Yes, but not all conditions work everywhere. Some are Frontend-only (e.g. getTSFE(), siteLanguage()), while others are Backend-only (e.g. backend.user.*, workspace.*).

getTSFE() is available only during Frontend rendering. If the condition runs in Backend, CLI, or Scheduler context, it will always evaluate to false.

Create custom conditions only for configuration-level decisions that cannot be expressed with built-in variables or functions. Avoid using them for business logic or performance-critical checks.

Yes. TypoScript conditions are evaluated frequently, which is why they should remain simple, deterministic, and fast. Heavy logic or external calls can negatively impact performance.

Your One-Stop Solutions for Custom TYPO3 Development

  • A Decade of TYPO3 Industry Experience
  • 350+ Successful TYPO3 Projects
  • 87% Repeat TYPO3 Customers
TYPO3 Service
wolfgang weber

Post a Comment

×