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.
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: