Host name in Shopware storefront and admin-area twig

Obtaining the host name from Shopware storefront and administration related code. E.g. From .twig and vue.js components.

166 views
d

By. Jacob

Edited: 2023-03-05 10:05

How to obtain the currently requested sales channel domain will depend on where you are doing it from. E.g. From .twig files used in the Shopware Storefront you can use app.request.get('sw-storefront-url'), and in the administration backend you can use the Shopware.Context.api.host property.

This actually works both in .twig files for the storefront, and when developing or overriding vue.js components in the administration backend.

Note. Both of these properties will result in. E.g. https://example.com (without trailing slash "/").

In PHP, I have found the most reliable way to obtain the host is simply to access the PHP $_SERVER['HTTP_HOST'] superglobal. While this is not typically recommended in an OOP context, unfortunately, the host available in the request object might be changed by Shopware and sometimes contain unexpected values – but this is not a problem when using $_SERVER['HTTP_HOST'].

Administration

When coding twig in the backend you can do like this:

<template>
  <div id="host_name">
  {{ Shopware.Context.api.host }}
  </div>
</template>

And inside the different lifecycle hooks in vue, you can simply do like this:

updated: function () {
  if ("undefined" !== typeof this.product && "undefined" !== typeof this.product.customFields && this.definedCount == 0) {
    ++this.definedCount;
    console.log(Shopware.Context.api.host);  
  }
},

Note. That the updated lifecycle hook fires multiple times doing the initial page load before the various objects, properties or variables are available. We are only interested in the initial update where the relevant entity we wish to access exist. So far, I have not figured out an easy way to do that in vue.js, so that's why I improvised with an if statement. E.g:

data() {
  return {
    definedCount: 0
  };
},
updated: function () {
  if ("undefined" !== typeof this.product && "undefined" !== typeof this.product.customFields && this.definedCount == 0) {
    ++this.definedCount;
    // ... More code here
  }
},

The ++this.definedCount; part increments the counter, and the if statement makes sure the code is only executed while the counter equals 0.. But, you do not need to think about this if you access data inside click triggered methods, of course.

Extra Tip: You can console.log(Shopware.Context) to learn which other properties are available in the context, and you need to do this from the vue.js component code, because you probably can not easily dump() in twig itself. I already tried :-/

Storefront

In the storefront you can access the host with the sw-storefront-url request attribute. E.g:

{% if 'https://example.com' == app.request.get('sw-storefront-url') %}
 <p>The host name matched the sw-storefront-url attribute!</p>
{% endif %}

Or, if you wish to output the host name directly in the twig HTML, you use double curly brace:

<p>The host name matched the {{ app.request.get('sw-storefront-url') }} attribute!</p>

Dumping the content of variables should also work in the storefront, but I find it better to simply dump these structures to a file with a custom function, since some objects can be too large to dump in the browser.

Tell us what you think:

  1. Sometimes we may to manually clear cached Shopware files to fix namespace issues.
  2. How to obtain the currently selected API language from Shopware vue components.
  3. How to access file system paths from storefront twig files in Shopware.
  4. How to get or change the currently selected sales channel in an Shopware sw-sales-channel-switch component.
  5. In this tutorial you will learn how to work with Shopware entities in a generic way from PHP, without having to specifically inject the repository in your services.xml file.

More in: Shopware