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.

TYPO3 Site Sets 

EXT:solr now provides TYPO3 site sets for the base configuration, optional frontend assets, OpenSearch and the shipped example configurations. For TYPO3 14 projects that do not use TypoScript template records, site set dependencies are the recommended way to include EXT:solr configuration.

See Site Sets for the full list of available site sets.

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.

Bugfix: BE Web Context Preservation During Indexing 

When the IndexQueueWorker scheduler task is dispatched from the BE web context (Scheduler module) or chained on the CLI via scheduler:run, the frontend sub-request executed during indexing replaced global state that the caller relies on:

  • $GLOBALS['BE_USER'] and $GLOBALS['LANG'] are overridden by the frontend BackendUserAuthenticator middleware.
  • $GLOBALS['TYPO3_REQUEST'] is reassigned by the frontend RequestHandler.
  • AssetCollector and PageRenderer singleton state is mutated by the frontend rendering chain.

The Scheduler module then crashed when rendering its task-list view after the task (TypeError on ModuleTemplate::getBackendUser(), or broken BE styles), and scheduler:run chaining multiple tasks crashed in DataHandler because the next task expected a real BackendUserAuthentication instance.

Fix: IndexingService::executeSubRequest() now snapshots all of this state before the sub-request and restores it in the finally block — for $GLOBALS keys preserving the "absent vs. null" distinction. The pattern is inspired by the testing-framework's FrameworkState class, scoped to the production state we observe getting tainted.

See #4628 and #4647.

Breaking Changes 

!!! jQuery Removed: Vanilla JavaScript Frontend 

The jQuery, jQuery UI, and associated plugin dependencies have been removed from all frontend JavaScript. All controllers (search, suggest, facet options, date range, numeric range) have been rewritten in vanilla JavaScript. The autoComplete.js library is now used for the suggest/autocomplete feature.

New dedicated CSS files (daterange.css, numericrange.css) replace the bundled jQuery UI stylesheet (jquery-ui.custom.css).

Migration: Remove any solr-jquery, solr-uri-jquery, and solr-ui (jQuery UI) asset references from your TypoScript includes and replace them with the updated example templates. See the Frontend / Autosuggest, Frontend / Facets, and Frontend / Ajax documentation chapters for updated examples.

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.

!!! Trailing Space Removed from searchResultClassName and searchResultSetClassName Keys 

The configuration keys $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['searchResultClassName '] and $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['searchResultSetClassName '] had an unintentional trailing space. The space has been removed.

Impact 

Code registering a custom search result class using the old key with a trailing space will silently fall back to the default class, since the key no longer matches.

Migration 

Remove the trailing space from the key in your ext_localconf.php:

// Before (broken — trailing space)
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['searchResultClassName '] = MySearchResult::class;
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['searchResultSetClassName '] = MySearchResultSet::class;

// After (correct)
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['searchResultClassName'] = MySearchResult::class;
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['searchResultSetClassName'] = MySearchResultSet::class;
Copied!

!!! Upgrade to Apache Solr 10.0.0 

Latest Apache Solr Release 10.0.0 required, EXT:solr 14 won't support older Apache Solr versions. Along with the switch to Apache Solr 10, Apache Lucene 10 is being used. A full reindexing is recommended. Please refer to the Apache Solr documentation to find out what major changes Solr 10 brings.

Solr 10 bundles Jetty 12, which strictly rejects ambiguous URI path encoding (HTTP 400). A previous workaround using double rawurlencode() for the managed synonyms and stopwords API has been removed, as it is incompatible with Jetty 12. Synonym base words and stop words containing non-ASCII characters (e.g. umlauts) are now handled correctly.

In Solr 10 the LocalTikaExtractionBackend (deprecated since Solr 9.10, SOLR-17961) was also removed. The tikaserver backend is now the only supported extraction backend. The /update/extract request handler has been removed from solrconfig.xml accordingly. Users relying on Solr Cell must use EXT:tika v14+ and provide a Tika Server or Tika app

!!! Deprecated dynamic Solr fields dropped 

Since EXT:solr 9 and Apache Solr 7 dynamic fields based on trie fields are marked as deprecated, these fields are now removed:

  • _tIntS (-> _intS)
  • *_tInt (-> _intM)
  • *_tLong (-> _longS)
  • *_tLong (-> _longM)
  • *_tFloat (-> _floatS)
  • *_tFloat (-> _floatM)
  • *_tDouble (-> _doubleS)
  • *_tDouble (-> _doubleS)
  • *_tDouble4 (-> _double4S)
  • *_tDouble4 (-> _double4M)
  • *_tDate (-> _dateS)
  • *_tDate (-> _dateM)

All Changes 

  • [BUGFIX] Preserve BE web context across indexing sub-request by @dkd-kaehm in #4647
  • [BUGFIX] fix suggestion query if routeEnhancer is set by @dkd-lehnebach in #4644
  • [BUGFIX] Improve assertion message in AccessProtectedContentTest by @dkd-kaehm in #4643
  • [BUGFIX] v14: remove extra x character in suggest_controller.js by @dkd-kaehm in 3c7cd960a
  • [BUGFIX] facet URL encoding mismatch (spaces) when using urlParameterStyle=assoc by @dkd-hauser in #4610
  • [BUGFIX] Correct field name casing for subTitle and navTitle in TypoScript queryFields by @amirarends in #4618
  • [FEATURE] Add site sets for all registered TypoScript templates by @dmitryd in #4622
  • [DOCS] Add documentation about site sets by @dmitryd in #4622
  • [DOCS] Update DynamicFieldTypes.rst by @daylightsoftware in #4512
  • [TASK] switch to stable/dev TYPO3 14.3.x by @dkd-kaehm in #4620
  • [TASK] replace backend module icons with TYPO3 14 style by @konradmichalik in #4611
  • [BUGFIX] Fix managed synonyms and stopwords API compatibility with Solr 10 by @dkd-dobberkau in #4562
  • [TASK] Drop deprecated Solr fields by @dkd-dobberkau in #4562
  • [TASK] Drop ExtractingRequestHandler for Solr 10 by @dkd-dobberkau in #4562
  • [TASK] Update solr-typo3-plugin to 7.0.0 for Solr 10 by @dkd-dobberkau in #4562
  • [TASK] Update Dockerfile and solr.xml for Solr 10 compatibility by @dkd-dobberkau in #4562
  • [TASK] Apache Solr 10 compatibility for configset by @dkd-dobberkau in #4562
  • [TASK] Adjust reports and status checks by @dkd-dobberkau in #4562
  • [TASK] Increase tmpfs size by @dkd-dobberkau in #4562
  • [!!!][BUGFIX] Remove space in searchResultClassName and searchResultSetClassName configuration keys by @beardcoder in #4226
  • [!!!][TASK] Remove jQuery dependency from frontend JavaScript by @dkd-lehnebach in #4619
  • [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