I've been using this example to eager load images, stored in an Assets field which is located in a Matrix field.

My query looks like this:

{% set entries = craft.entries.section('project')
.with(['projectMatrix.imageBlock:imageFile']) %}

Where projectMatrix is a Matrix field, imageBlock is a Matrix block type and imageFile is an Asset field inside imageBlock.

But how do I reference the that image in my templates?

{% for entry in entries %}

{% set matrixImage = entry.projectMatrix.type('imageBlock')[0].imageFile[0] ?? null %}


{% endfor %}

This is always be null, when eager loaded

1 Answer 1


The reason this doesn't work is because .type('image') won't work with eager loading. Eager loading removes the ability to use ElementCriteriaModel methods.

From the docs:

When the assets aren’t eager-loaded, entry.assetsField gives you an ElementCriteriaModel that is preconfigured to return the related assets once they’re requested (e.g. when first() is called).

However when the assets are eager-loaded, entry.assetsField gets overwritten with an array of the eager-loaded assets. So first(), find(), and other ElementCriteriaModel methods are not available. Instead you must stick to the standard array syntaxes.

As a work around, you could use a for loop to match only Matrix blocks of a particular type instead:

{% for block in entry.projectMatrix if block.type == 'imageBlock' %}
  {% set matrixImage = block.imageFile[0] %}
{% endfor %}

If you only want the first image block type:

{% for block in entry.projectMatrix if block.type == 'imageBlock' %}
  {% if loop.index == 1 %}
    {% set matrixImage = block.imageFile[0] %}
  {% endif %}
{% endfor %}
  • Ah! It makes sense, thank you for explaining :)
    – Slebbo
    Mar 15, 2018 at 11:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.