Eager-Loading Assets in Matrix 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
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 %}