Additionally, Kirby copies all media files that you upload to the
/content folder into the media folder.
There are several reasons for this architectural decision:
- Unless you are on shared hosting, you can move the content folder outside the doc root for more security, so that it is not accessible publicly, while files that need to be accessible can be accessed through the public media folder.
- With the content folder out of the doc root or access to the content folder blocked through server settings, you can prevent access to files through permissions.
- The hashed folder names allow heavy caching configurations on the server with far-future expiry times.
- By proxying the calls to files in general it is also possible to create plugins that move the files entirely off the server (e.g. to S3) and fetch them from there. Or to use a service like Imgix or Cloudinary instead of Kirby's media API.
- More stable files URLs that are not affected by changing sorting numbers of the page folders they live in.
Of course this means that all files are duplicated and use double the space on the server. However, storage space is usually not an issue today.
If you don't like this behaviour, or run into storage issues on media heavy sites, you can create a little plugin that allows you to continue to serve your files from the content folder, either altogether or in parts.
/plugins folder, create a new folder called
/file-component and an
index.php inside it.
Before we can test this, we have to do one additional step. The default
.htaccess file included with Kirby's Starter- and PlainKits blocks direct access to the
content folder with this line:
You therefore have to remove or comment this line to make the plugin work.
With this plugin in place, your files will no longer be copied to the media folder but be served from the
/content folder instead. Files will now be served with a URL like
You can also decide to serve only parts of your files from the
/content folder while all other files are still served from the media folder:
In the example, we serve only video files from the
/content folder while all other files are still copied to the
The conditions here are up to you, instead of filtering by file type, you can for example do this based on template.