TYPO3 Migration Guide: Converting typo3conf Assets for Composer Workflow
With the growing need for cleaner and more reliable TYPO3 workflows, migrating assets to Composer has become a valuable step for developers. TYPO3 Composer Migration helps streamline project structure, improve asset handling, and make future maintenance easier. This guide covers the essential steps to transition from typo3conf assets to a Composer-based TYPO3 setup.
Migrating TYPO3 Assets from typo3conf/ext to Composer
With modern Composer-based TYPO3 projects, extensions are no longer meant to be accessed directly through typo3conf/ext/. Their public files are exposed through the _assets directory.
This change improves security, structure, and maintainability because only files from Resources/Public/ are publicly accessible.
What Changed?
Older TYPO3 projects commonly used:
typo3conf/ext/site_package/Resources/Public/ Composer-based projects use:
vendor/ packages/ public/_assets/ Only an extension's Resources/Public/ folder is exposed to the browser.
Find Old Asset References
Start by searching the complete project for:
typo3conf/ext/ Check the following areas:
- Fluid templates
- CSS and SCSS
- JavaScript
- PHP
- TypoScript
- TSconfig
- RTE configuration
- Frontend build tools
Do not simply replace the old path with an _assets path. Each file type should use the proper TYPO3 method.
Fluid Templates
Avoid hardcoded paths such as:
<img src="/typo3conf/ext/site_package/Resources/Public/Images/logo.svg"> Instead, use TYPO3's resource ViewHelper:
<img src="{f:uri.resource(path: 'Images/logo.svg')}" alt="Logo"> This allows TYPO3 to generate the correct public URL automatically.
CSS
If the CSS file and asset belong to the same extension, relative paths are usually the easiest solution:
background-image: url("../Images/image.jpg"); Avoid hardcoding paths such as /_assets/<hash>/.... The generated hash can change, so your CSS should not depend on it.
JavaScript
Do not hardcode TYPO3 extension paths inside JavaScript. Instead, generate the asset URL in Fluid and pass it through HTML:
<div data-icon="{f:uri.resource(path: 'Icons/marker.svg')}"></div> JavaScript can then read the generated value from the data attribute.
PHP
Always remember the difference between a filesystem path and a public URL.
For server-side files, use TYPO3's resource handling:
GeneralUtility::getFileAbsFileName( 'EXT:site_package/Resources/Public/Images/logo.png' ); Do not use filesystem paths as browser URLs.
TypoScript, TSconfig and RTE
Where supported, use EXT: references instead of old typo3conf/ext paths.
EXT:site_package/Resources/Public/Images/logo.png Also check TSconfig and RTE settings because old asset paths can easily remain there unnoticed.
Do Not Edit _assets Manually
The _assets directory is generated and managed by TYPO3 and Composer.
Do not:
- Hardcode its hash
- Rename generated directories
- Modify its symlinks manually
- Build application logic around the generated hash
If necessary, regenerate the asset links with:
composer dumpautoload Quick Migration Checklist
- Search the project for
typo3conf/ext/. - Keep public files inside
Resources/Public/. - Use
f:uri.resourcein Fluid. - Use relative paths for related CSS assets.
- Pass generated URLs to JavaScript when needed.
- Use
EXT:references in TypoScript and configuration. - Check TSconfig, RTE, and frontend build tools.
- Never hardcode
_assets/<hash>/. - Do not manually modify
_assets. - Clear caches and test CSS, JavaScript, images, fonts, and other public files.
Conclusion
Migrating TYPO3 assets to Composer is more than changing a folder path. The key is to stop using hardcoded typo3conf/ext and _assets URLs and let TYPO3 handle asset paths correctly. Using Resources/Public, f:uri.resource, EXT: references, and relative paths keeps the project secure, clean, and easier to maintain.
