Releases 14.0 

Release 14.0.0 

This is a new major release for TYPO3 14 LTS.

New in this release 

TYPO3 14 LTS Compatibility 

EXT:solr has been fully adapted for TYPO3 14 LTS, including Fluid v5 ViewHelper compatibility, TCA changes, deprecation removals, and testing framework updates.

XLIFF 2.0 Migration 

All language files have been migrated from XLIFF 1.2 to XLIFF 2.0 format.

Parallel Solr Worker Cores for Integration Tests 

Integration tests now use parallel Solr worker cores via paratest, significantly improving test execution speed.

Event Listener Migration to PHP Attributes 

Event listeners have been refactored to use the #[AsEventListener] PHP attribute instead of Services.yaml tag registration, following TYPO3 14 best practices.

Unified Sub-Request Indexing Pipeline 

The page indexing system has been completely rewritten. The legacy HTTP-based PageIndexer (which made real HTTP round-trips via X-Tx-Solr-Iq headers) has been replaced by a unified in-process sub-request pipeline using TYPO3's Application::handle().

Key changes:

  • IndexingService orchestrates all indexing via Application::handle() sub-requests — no more HTTP round-trips
  • SolrIndexingMiddleware handles page rendering, document creation, and Solr submission within the standard TYPO3 middleware stack
  • UserGroupDetectionMiddleware + UserGroupDetector detect frontend user groups during page rendering without Singleton state or TCA manipulation
  • CliEnvironment and forcedWebRoot scheduler option removed — sub-requests use chdir(Environment::getPublicPath()) to ensure correct working directory
  • 12.7% faster indexing (493.9s → 431.3s for 59 pages) with  3,200 lines removed

See #4559 and #4598 for details.

Bugfix: No c:0 Variant on fe_group-restricted Pages 

Two interrelated bugs in the new sub-request indexing pipeline caused access-protected pages to be indexed with incorrect Solr documents.

Bug 1 — Spurious ``c:0`` variant from global template content: During the findUserGroups sub-request, TYPO3 renders the full page including global template content (footer, navigation) from other pages. Content elements without fe_group restriction in these template areas caused UserGroupDetector to collect group 0, which then triggered a c:0 Solr variant even for pages where all actual page content is access-restricted. With fe_group=1 on the page, the c:0 variant was never meaningfully accessible (its access rootline already required group 1), but it polluted the index with empty or incorrect documents.

Fix: When pageUserGroup > 0, group 0 is removed from the detected access groups. The page's own group is added as a fallback so that users holding only the page group can still find the page in search results.

Bug 2 — Protected content leaking into the ``c:0`` variant: When indexing the c:0 variant (anonymous rendering), FrontendGroupsModifier unconditionally added pageUserGroup to the faked frontend groups. This granted access to fe_group-restricted content elements during the anonymous rendering sub-request, causing protected content to appear in the public Solr document — a potential content disclosure issue.

Fix: pageUserGroup is now only added to the faked groups when userGroup > 0 (i.e. not during the anonymous c:0 rendering).

As a result, pages with fe_group restriction no longer produce a c:0 Solr document. Instead, the page's own group (e.g. c:1) is used as the base content access variant.

Breaking Changes 

Unified Site Hash Strategy 

Introduced in solr v13.1, and now implemented as default, the site hash strategy is now based on the site identifier and not on the domain anymore, making the site hash calculation more robust across sites with multiple domains.

The extension configuration setting: siteHashStrategy has been removed without substitution.

The PSR-14 event AfterDomainHasBeenDeterminedForSiteEvent has been removed, as it has been superseded by AfterSiteHashHasBeenDeterminedForSiteEvent.

If you upgrade from < 13.1, it is recommended to re-index all solr cores completely.

!!! DataUpdateHandler::removeFromIndexAndQueueWhenItemInQueue() removed 

The deprecated method DataUpdateHandler::removeFromIndexAndQueueWhenItemInQueue(string $recordTable, int $recordUid): void has been removed. Use DataUpdateHandler::removeFromIndexAndQueue() directly instead.

Impact 

Code overriding removeFromIndexAndQueueWhenItemInQueue() or calling it from a subclass

Replace every call to removeFromIndexAndQueueWhenItemInQueue() with a direct call to removeFromIndexAndQueue().

The queue-containment check that was part of the old method is not needed: removeFromIndexAndQueue() / GarbageHandler::collectGarbage() handle that case gracefully.

!!! PageIndexer::isPageIndexable() removed 

The deprecated method PageIndexer::isPageIndexable(Item $item): bool has been removed. Use PageIndexer::isPageEnabled(array $record): bool instead.

Impact 

Code overriding isPageIndexable() in a custom PageIndexer subclass

Rename method isPageIndexable to isPageEnabled() and adjust the signature to accept an array (the page record) instead of an Item object:

!!! RecordUpdatedEvent no longer covers record insertions – use RecordInsertedEvent 

A dedicated RecordInsertedEvent has been introduced for record creations. The RecordUpdatedEvent now only fires for updates; the deprecated $isNewRecord property, its constructor parameter, and the isNewRecord() method have been removed from RecordUpdatedEvent.

Previously RecordUpdatedEvent was dispatched for both new records and updates, with isNewRecord() acting as a flag to distinguish the two cases. In v14 these are two distinct events.

Impact 

Listeners checking $event->isNewRecord()

Register your listener for RecordInsertedEvent to handle creations, and for RecordUpdatedEvent to handle updates. Remove any isNewRecord() checks:

# Before – one listener covering both cases
tags:
  - name: event.listener
    event: ApacheSolrForTypo3\Solr\Domain\Index\Queue\UpdateHandler\Events\RecordUpdatedEvent

# After – separate registrations
tags:
  - name: event.listener
    event: ApacheSolrForTypo3\Solr\Domain\Index\Queue\UpdateHandler\Events\RecordInsertedEvent
  - name: event.listener
    event: ApacheSolrForTypo3\Solr\Domain\Index\Queue\UpdateHandler\Events\RecordUpdatedEvent
Copied!

Code instantiating new RecordUpdatedEvent(..., isNewRecord: true)

Replace with new RecordInsertedEvent($uid, $table, $fields).

!!! Item properties are now non-nullable with strict validation 

Item constructor properties (item_uid, indexing_configuration, changed) are now non-nullable and validated strictly. CSV fixtures for integration tests must include all required columns.

!!! Legacy PageIndexer system removed 

The HTTP-based page indexing system has been completely removed and replaced by the unified sub-request pipeline. The following classes no longer exist:

  • \IndexQueue\PageIndexer — replaced by \IndexQueue\IndexingService
  • \IndexQueue\PageIndexerRequest — replaced by \IndexQueue\IndexingInstructions
  • \IndexQueue\PageIndexerResponse — replaced by JsonResponse
  • \IndexQueue\PageIndexerRequestHandler
  • \IndexQueue\PageIndexerDataUrlModifier (interface)
  • \IndexQueue\FrontendHelper\Manager
  • \IndexQueue\FrontendHelper\FrontendHelper (interface)
  • \IndexQueue\FrontendHelper\PageIndexer (event listener)
  • \Middleware\PageIndexerInitialization
  • \System\Environment\CliEnvironment
  • \System\Environment\WebRootAllReadyDefinedException

The UserGroupDetector and AuthorizationService have been moved from \IndexQueue\FrontendHelper to the Middleware namespace.

The forcedWebRoot scheduler task option has been removed from IndexQueueWorkerTask and IndexQueueWorkerTaskAdditionalFieldProvider.

Impact 

Custom PageIndexer subclasses must be rewritten to use the new pipeline. Register event listeners for AfterPageDocumentIsCreatedForIndexingEvent or BeforeDocumentIsProcessedForIndexingEvent instead.

Code referencing PageIndexerRequest::SOLR_INDEX_HEADER (X-Tx-Solr-Iq) should check the solr.indexingInstructions request attribute instead.

Code using CliEnvironment for web root initialization should remove those calls — the sub-request pipeline handles CWD automatically.

All Changes 

  • [BUGFIX] Prevent c:0 variant and content leakage on fe_group-restricted pages by @dkd-kaehm in #4559
  • [!!!][TASK] Remove legacy PageIndexer system and migrate to IndexingInstructions by @dkd-kaehm in #4559
  • [TASK] Set CWD to public path during sub-requests and remove CliEnvironment by @dkd-kaehm in #4559
  • [!!!][TASK] Refactor indexing stack to unified TYPO3 core sub-requests by @dkd-kaehm in #4559
  • [TASK] Upgrade to typo3/testing-framework 9.5.0 by @dkd-kaehm in #4604
  • [TASK] Fix IconFactory::mapRecordTypeToIconIdentifier() call for TYPO3 14 by @dkd-kaehm in #4604
  • [TASK] Upgrade GitHub Actions to latest versions by @dkd-kaehm in #4601
  • [TASK] Implement deferred Solr cleanup + fix worker core isolation by @dkd-kaehm in #4594
  • [TASK] Run integration tests without processIsolation by @bmack in #4594
  • [TASK] Implement parallel Solr worker cores for paratest integration tests by @dkd-kaehm in #4594
  • [TASK] Convert AbstractUriViewHelper to instance properties by @dkd-kaehm in #4594
  • [TASK] Refactor event listeners with AsEventListener attribute by @sfroemkenjw in #4588
  • [BUGFIX] GeneralUtility::trimExplode(): Argument #2 ($string) must be of type string, int given by @kitzberger in #4511
  • [BUGFIX] Cast result offset to integer by @Nowak in #4529
  • [TASK] Refactor and optimize Classification handling by @sfroemkenjw in #4583
  • [TASK] Migrate xlf files of TYPO3 modules to XLIFF format 2.0 by @sfroemkenjw in #4575
  • [TASK] Refactor SettingsPreviewOnPlugins to EventListener by @sfroemkenjw in #4576
  • [TASK] Refactor static function usage in ViewHelpers by @sfroemkenjw in #4582
  • [TASK] Refactor facet ViewHelpers to use shared trait by @sfroemkenjw in #4580
  • [TASK] Fix namespace typo in SearchFormViewHelperTest by @sfroemkenjw in #4581
  • [TASK] Refactor SearchFormViewHelper by @sfroemkenjw in #4563
  • [TASK] Refactor IsStringViewHelperTest to IntegrationTestBase by @sfroemkenjw in #4578
  • [TASK] Simplify test setup in SetUpFacetItemViewHelper by @sfroemkenjw in #4577
  • [TASK] Speed up tests by sending autoCommit for updates by @bmack in #4565
  • [TASK] Refactor UnitTests for Rootline and RootlineElement by @sfroemkenjw in #4574
  • [!!!][TASK] Introduce RecordInsertedEvent, drop isNewRecord from RecordUpdatedEvent by @dkd-friedrich in #4560
  • [!!!][TASK] Remove deprecated DataUpdateHandler::removeFromIndexAndQueueWhenItemInQueue() by @dkd-friedrich in #4560
  • [!!!][TASK] Remove deprecated PageIndexer::isPageIndexable() for v14 by @dkd-friedrich in #4560
  • [!!!][TASK] Remove QueueInitializationServiceAwareInterface and related Queue API by @dkd-friedrich in #4560
  • [TASK] Update test extensions to use 'apache-solr-for-typo3/solr' by @sfroemkenjw in #4573
  • [TASK] Simplify unit tests configuration by @dkd-kaehm in #4571
  • [TASK] Remove unused TYPO3 Core context initialization in integration tests by @sfroemkenjw in #4568
  • [TASK] Update test extension path in IntegrationTestBase by @sfroemkenjw in #4567
  • [TASK] Refactor DI handling for FrequentSearchesService by @sfroemkenjw in #4548
  • [TASK] Refactor GroupItemPaginateViewHelper by @sfroemkenjw in #4549
  • [BUGFIX] Adapt tests by @bmack in #4546
  • [TASK] Remove PSR-14 event, and update RST file by @bmack in #4546
  • [!!!][TASK] Remove site hash strategy flag by @bmack in #4546
  • [BUGFIX] Polish infobox to align with current ContextualFeedbackSeverity by @aarends in #4551
  • [TASK] Prepare v14 release notes by @dkd-friedrich in #4547
  • [BUGFIX] Remove TSFE from access component by @garfieldius in #4544
  • [BUGFIX] Allow GroupItemPaginateViewHelper template to be overridden by @jschlier in #4542
  • [TASK] Replace removed FormResultCompiler with FormResultFactory for TYPO3 14 by @dkd-kaehm in #4528
  • [TASK] Fix access protected content indexing for TYPO3 14 by @dkd-kaehm in #4528
  • [TASK] Speed-up integration tests by skipping database initialization by @dkd-kaehm in #4528
  • [TASK] Fix integration tests for TYPO3 14 compatibility by @dkd-kaehm in #4528
  • [TASK] Make Item properties non-nullable with strict validation by @dkd-kaehm in #4528
  • [TASK] Fix FlexForm handling in SettingsPreviewOnPlugins for TYPO3 14 by @dkd-kaehm in #4528
  • [TASK] Fix TCA searchFields deprecation and ContentObjectRenderer for TYPO3 14 by @dkd-kaehm in #4528
  • [TASK] Refactor FrontendEnvironment/Tsfe to FrontendSimulation/FrontendAwareEnvironment by @dkd-kaehm in #4528
  • [TASK] Fix ViewHelper classes for TYPO3 14 / Fluid v5 compatibility by @dkd-kaehm in #4528
  • [TASK] Fix Report classes for TYPO3 14 compatibility by @dkd-kaehm in #4528
  • [TASK] Upgrade deps for TYPO3 14 by @dkd-kaehm in #4528
  • [TASK] Prepare schema/configset for dev-14.0.x by @dkd-kaehm in #4528
  • [TASK] Remove ext_econf.php file by @dkd-kaehm in #4528
  • [BUGFIX] Respect plugin TS in RelevanceComponent by @helhum in #4532
  • [BUGFIX] Catch InvalidArgumentException for missing site languages in GarbageHandler by @mwohlschlegel in #4534
  • [BUGFIX] Add headers palette to solr plugin CType TCA definitions by @dkd-kaehm in #4536
  • [BUGFIX] CS issues 2026.02.05 by @dkd-kaehm in #4526
  • [DOCS] Update version matrix by @dkd-friedrich in #4518
  • [SECURITY] Update to Apache Solr 9.10.1 by @dkd-friedrich in #4518
  • [DOCS] Update version matrix in main for current versions by @dkd-kaehm in 91c455b8a

Contributors 

Like always this release would not have been possible without the help from our awesome community. Here are the contributors to this release.

(patches, comments, bug reports, reviews, ... in alphabetical order)

Also a big thank you to our partners who have already concluded one of our new development participation packages such as Apache Solr EB for TYPO3 14 LTS (Feature).

How to Get Involved 

There are many ways to get involved with Apache Solr for TYPO3:

  • Submit bug reports and feature requests on GitHub
  • Ask or help or answer questions in our Slack channel
  • Provide patches through Pull Request or review and comment on existing Pull Requests
  • Go to www.typo3-solr.com or call dkd to sponsor the ongoing development of Apache Solr for TYPO3

Support us by becoming an EB partner:

https://shop.dkd.de/Produkte/Apache-Solr-fuer-TYPO3/

or call:

+49 (0)69 - 2475218 0