Locally Testing Contao Extensions

by Thomas Urban

On developing new extension for Contao CMS you might want to test it first with an existing installation of Contao rather than publishing it. One approach is to use a local repository and require the extension in development from there.

First choose a folder to contain your extension to be tested. This folder must be located on same server as your Contao installation. Due to a composer constraints it must not be located in folder containing files of your website. So, if your website is located in /var/www your extension might reside in /home/johndoe/extension. It musnt't reside in /var/www/extension.

Open composer.json file of your Contao installation (which would be /var/www/composer.json in case illustrated before) and add definition of local repository:

"repositories": [
        "type": "path",
        "url": "/home/johndoe/extension"

Use absolute pathname of folder containing your particular extension. Composer will use this path to check the contained composer.json file e.g. for matching the package's name as used on requiring it which is the next step to add the extension to your existing Contao installation. Open CLI in folder of your Contao installation and run

composer require "company/name @dev"

The @dev is used to prevent the need for proper version number. The company/name is the full name of your package as defined in your extension's /home/johndoe/extension/composer.json file.

Keep on Developing!

As a result the local folder containing your package is injected into the Contao installation using a symbolic link. However, succeeding changes of files in your package won't instantly affect Contao's behaviour due to Symfony's caching. Thus you need to rebuild the cache after changing files of your new extension:

vendor/bin/contao-console cache:clear
vendor/bin/contao-console cache:warmup


Using open_basedir restrictions to tighten security on your Contao installation might affect the described use case when locally installing development package using some folder which isn't covered by your open_basedir setting. Make sure this restriction is covering the folder for symlinks pointing to some external folder will definitely breach the open_basedir restriction resulting in all requests failing with 500 Internal Server Error and adding some log entry regarding the breach.

Go back