TYPO3 Migration Guide: Converting typo3conf Assets for Composer Workflow

in #typo3 • 7 days ago

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.

TYPO3 Composer Migration.jpg

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.resource in 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.