I'm building a small Craft site to function as a content backend, exposing all of the content via the ElementAPI.

One field I'm retrieving and displaying in the API is the URL on Amazon S3 for an image asset that's contained in a Matrix field.

What I'd ideally like to do is, when the user uploads this image and it's added to the S3 bucket, to be able to access S3 URLs for the small, medium and large cropped Image Transforms that I've defined. Then, I can make all of these available as an Element API endpoint.

My understanding of Image Transforms and S3 is that Craft usually handles this on-the-fly when an image is referenced in a frontend template. But is there a way to do this when there will be no frontend templates, and the only way that information will be accessed is via the Element API?


Yep, you can access transforms the same way you would in a template - via the asset’s getUrl() method.

That $transform argument can either be a string, set to the handle of one of your transforms in Settings → Assets → Transforms, or in can be an array that defines the transform settings at runtime. (Or it can be null if you just want the source image URL.)

Keep in mind that if the transform hasn’t been created yet, the default behavior of getUrl() will be to return a temporary URL that actually triggers the transform generation process, and responds with a redirect pointing to the new image once it has actually been created. But in this case you’d probably prefer for the transform to be created in the actual Element API request, so the actual URL can be returned right off the bat. You can do that by enabling the generateTransformsBeforePageLoad config setting at runtime.

So your transformer function would look something like this:

'transformer' => function(EntryModel $entry) {
    // Generate new image transforms right away
    craft()->config->set('generateTransformsBeforePageLoad', true);

    $blockData = [];

    foreach ($entry->myMatrixField as $block) {
        $image = $block->myAssetsField->first();

        if ($image) {
            $imageUrl = $image->getUrl('myTransform');
        } else {
            $imageUrl = null;

        $blockData[] = [
            'image' => $imageUrl,
            // ...

    return [
        'blocks' => $blockData,
        // ...
  • Fantastic--this worked really nicely and I'm now able to pull all my image sizes into the JSON response. Thanks for your help!
    – Jon Lay
    Feb 1 '16 at 2:13

For Craft3, we can also use

Craft::$app->getAssets()->getAssetUrl($image,'myTransform', true)

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.