There are a few places where I am calling ImageStyle::load('style')->buildUrl($uri) to get a physical file path of an image.

After enabling HTTPS and forcing all traffic to use HTTPS, I noticed that this will only return http:// at the start of the url, and not https:// causing mixed mode flag in the browser.

Is there a way to do this and get the correct protocol? Can I not just obtain the relative path to the file instead? I notice that this method has hardcoded 'absolute' => TRUE when building the url to return.

Edit: fields using the normal rendering method i.e. {{ content.field_image }} have the correct protocol and do not cause an issue.

Here is the code I am using to generate the variable:

 * Implements hook_preprocess_node().
 * @param $variables
function mytheme_preprocess_node(&$variables) {
  $node = $variables['elements']['#node'];
  $bundle = $node->bundle();

  if ($bundle =='homepage' && $variables['elements']['#view_mode'] == 'hero') {
    $hero_image = $node->get('field_hero_image')->getValue();

    if (!empty($hero_image)) {
      $entity = Media::load($hero_image[0]['target_id']);
      $variables['hero_image'] = ImageStyle::load('homepage_hero')->buildUrl($entity->field_image->entity->getFileUri());

In the node view mode twig template:

  {% if node.field_hero_image is not empty %}
    <div class="hero__graphic" style="background-image: url({{ hero_image }});"></div>
  {% endif %}

2 Answers 2


You can use file_url_transform_relative():

 * Transforms an absolute URL of a local file to a relative URL.
 * May be useful to prevent problems on multisite set-ups and prevent mixed
 * content errors when using HTTPS + HTTP.
 * @param string $file_url
 *   A file URL of a local file as generated by file_create_url().
 * @return string
 *   If the file URL indeed pointed to a local file and was indeed absolute,
 *   then the transformed, relative URL to the local file. Otherwise: the
 *   original value of $file_url.
 * @see file_create_url()
function file_url_transform_relative($file_url) {
  • This is what core is doing everywhere to solve problems when using mixed mode. But it should actually default to https if you have only https. Which is recommended anyway
    – Berdir
    Mar 2, 2017 at 7:28

You could try altering your base_url by un-commenting the following line in settings.php and changing the http to https.

 * Public file base URL:
 * An alternative base URL to be used for serving public files. This must
 * include any leading directory path.
 * A different value from the domain used by Drupal to be used for accessing
 * public files. This can be used for a simple CDN integration, or to improve
 * security by serving user-uploaded files from a different domain or subdomain
 * pointing to the same server. Do not include a trailing slash.
# $settings['file_public_base_url'] = 'http://downloads.example.com/files';

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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