Rethinking Volume Subfolders

Folder Stampede

There are a lot of ways you could go about organizing your site’s assets, and the “right” choice always depends on the site.

That’s why Craft has always featured highly flexible asset organization, with unlimited volumes and nestable subfolders.

Since 1.0, volume subfolders have been displayed as nested element sources, tucked away below each volume.

Asset index with subfolder sources

When we were designing asset indexes, that decision felt obvious. The whole point of element sources is to navigate across all the available elements, so of course it made sense to list subfolders as asset sources, and establish a 1-to-1 connection between sources and physical folders.


Over the years, a few problems with this approach have emerged.

  • Aesthetics: Subfolders have admittedly always been a little awkward to look at, due to the casing changes compared to their parent volume names.
  • Usability and accessibility: It’s never been very obvious that it’s possible to create new subfolders by right-clicking on a volume or subfolder, or to move folders and assets by dragging them. And these actions have been completely inaccessible for mobile and screen reader users.
  • UI constraints: Each nesting level gets more left-hand padding, which reduces the remaining space for the subfolder label. You can only get about three levels deep before running out of ample space.
  • Scalability constraints: All element sources need to be included in the DOM on page load, and initialized in JavaScript. If there are hundreds or thousands of sources to process, the browser will get bogged down.

That last one is especially damning when you consider that Assets fields have the ability to store assets in dynamically-generated subfolders named after the entry ID, user ID, etc. It’s not uncommon for a site to launch with everything working smoothly, only for the Assets index page to become unbearably slow (or worse) after a few months of content entry.

Possible Solutions

The scalability problem has been known for some time, but we’ve been stumped on how to solve it. We’ve done our best to optimize and defer the source initialization code, but there’s only so much that can be done. A proper fix will need to be more drastic.

One idea we’ve kicked around for a while was to have nested sources registered to a database table, which would enable them to be paginated or otherwise lazy-loaded via Ajax. More recently we considered creating some sort of source-resolving interface that elements could choose to implement if needed, and sort out how sources are actually stored on their own.

But paginating sources wouldn’t solve any of the other problems plaguing subfolders. If anything it would be a net loss for usability, while simultaneously making the code more complex. Which is why it hasn’t happened yet.

The other option is to move subfolders out of the sidebar and into the listing pane. That sounds good on paper, except for one problem: folders aren’t elements. And the entire element index infrastructure was designed for displaying elements.

We thought maybe down the road we could convert volume folders into specialized asset elements. Doing so would enable them to be included in asset queries alongside existing assets. But the migration to handle that conversion would be a painful one—particularly for the sites that need this change the most.

The Answer

A couple weeks ago, while brainstorming The Subfolder Situation for the umpteenth time, I had a default mode network moment. I remembered that each element type is ultimately responsible for its indexes’ listing pane contents. Which means there’s nothing stopping Asset::indexHtml() from going a bit against the grain and showing results that aren’t actually assets. Like, folders.

The idea proved to be viable. Listing folders within the main pane feels intuitive, scales well, and doesn’t feel too hacky behind the scenes. So we’ve been fleshing out the change over the past two weeks, and I’m thrilled to report that our new solution to volume folder UI is just about fully baked!

Asset index with inline folders

Folders get paginated along with the assets, so there’s never more than 100 folders loaded and displayed at once. And they get factored into searches as well, so you can quickly find a specific folder with ease.

Clicking on a folder will refresh the listing pane with subfolders and assets within that folder. As you drill down, a new “source path” component will be updated to reveal your current location within the volume.

Asset index subfolder path

Within the source path component, the currently-active folder will get an action menu, with “New subfolder”, “Rename folder”, “Move folder”, and “Delete folder” options.

We’ve also done away with all drag-and-drop asset/subfolder interactions, in favor of a new “Move” bulk asset action which can be activated for folders, assets, or both. It opens a folder selection modal, where a new target location can be chosen for the selected items.

Asset index “Move to” modal

We’re so excited about this change, we decided to make it for both Craft 3.8 and 4.4. Both of those releases are in active development, and will be released in tandem in the coming weeks.

Blog Home
2022 in Review