Search and privacy
Full-text search with Elasticsearch: search field, index, updates, failure behaviour – and why the website does without a CDN.
Searching
The search field at the top right, to the left of DE | EN, sends the query to the Search page (/en/search, German /suche). There, the “Search” plugin shows the results in the current language, each with its path, title and highlighted text passages. With more than ten results, you can page through them.
- All words must occur. Small typos are tolerated: “Kaycloak” finds “Keycloak”.
- The last word also counts as the beginning of a word: “Dockerf” finds “Dockerfile”.
- Word forms are merged: “volumes” finds “volume”, “Datenbanken” finds “Datenbank”.
The search index
Each language has its own index, typo3_0_de and typo3_1_en, with German and English stemming respectively. The index contains title, subtitle, abstract, description and all content elements of the publicly visible standard pages.
Not indexed are:
- hidden pages and content, and those outside their start/stop date,
- access-restricted pages (frontend user groups),
- pages with the option “No search” (tab Behaviour), such as the search page itself,
- English pages without a translation.
The index is updated in three ways:
| When | How |
|---|---|
| saving, moving, hiding or deleting in the backend | immediately, through a DataHandler hook |
| every 15 minutes | full sync in the scheduler container |
on every start of the php container | full sync in the entrypoint |
docker compose exec -u www-data php vendor/bin/typo3 search:index # sync manually
Search page
During the first installation, typo3 site:setup-search creates the “Search” page with the plugin. It is not shown in the menu and is not searchable itself. Its page ID is stored in the site setting sitePackage.searchPageUid (file config/sites/main/settings.yaml, in the backend under Sites → Settings). This is how the search field knows its target. If nothing is set there, the search field stays hidden.
In an existing installation without a search page:
docker compose exec -u www-data php vendor/bin/typo3 site:setup-search
docker compose exec -u www-data php vendor/bin/typo3 cache:flush
Running Elasticsearch
- Access: user
elasticwith the passwordELASTICSEARCH_PASSWORDfrom.env. The service publishes no port; onlyphpandschedulerreach it on the Docker network. - Memory:
ELASTICSEARCH_JAVA_OPTSsets the heap, 512 MB by default. The container needs about twice that much RAM. - Failure: if Elasticsearch is not running, TYPO3 still starts. The search page reports “unavailable”, saving in the backend keeps working, and the TYPO3 log contains a warning. At most 15 minutes after it is back, the index is up to date again.
- Data: the index lives in the
es-datavolume. It can be rebuilt from the database at any time and is therefore not part of the backup.
# show indices and document counts
docker compose exec elasticsearch sh -c \
'curl -s -u "elastic:$ELASTIC_PASSWORD" "localhost:9200/_cat/indices?v"'
Privacy: no CDNs
Every file a browser loads from a third-party server transmits the visitor’s IP address to it. Fonts, icons or scripts from a CDN would therefore require a legal basis under the GDPR. The appliance avoids this entirely: all resources come from your own server.
- Icons: Font Awesome Free 7.3.1 lives in the site package under
Resources/Public/Vendor/fontawesome/(CSS, web fonts and licence). It was downloaded once from npm and verified against the published checksum. - Font: the device’s system font (
system-ui), no web fonts. - Elasticsearch: the automatic download of the GeoIP database, a connection to Elastic, is switched off, and so is machine learning.
Use icons in a template like this:
<i class="fa-solid fa-magnifying-glass" aria-hidden="true"></i>