How to customize shipping address template
In the previous article, I have mentioned that the checkout of Magento includes two steps which are Shipping Information and Review and Payment Information.
On the Shipping Information checkout step, all addresses can be previously saved by a shopper. Then that shopper can select one which will be used for shipping just by clicking on that address. Although the default address renderers cover most of the use cases, Magento still allows you to register custom address renderer to create a new address type.
In today’s post, I will guide you on how to custom shipping address renderer on Magento 2.
How to customize shipping address template in 7 steps:
- Step 1: Create JS renderer component
- Step 2: Create a template for shipping address renderer
- Step 3: Create JS model for shipping rate processor
- Step 4: Create JS model for shipping address saving processor
- Step 5: Create JS component registering processors
- Step 6: Declare new components in checkout page layout
- Step 7: Add shipping address renderer to
Ship-To
block
Step 1: Create JS renderer component
You should implement your shipping address renderer as a JavaScript UI component. It has to be a RequireJS module, and has to return a factory function, that takes a configurable object.
To ensure compatibility, upgradability, and easy maintenance, please add your customizations in a separate module instead of the default Magento code. Besides, if you want your checkout customization to be applied correctly, your custom module has to depend on the Magento_Checkout
module. The module’s composer.jso
is the place where module dependencies are specified. And the Ui
should not be used for your custom module name as %Vendor%_Ui
notation is required when specifying paths, which might lead to some issues.
In the directory of your custom module, generate the file component’s .js
. This file must be located under the directory <your_module_dir>/view/frontend/web/js/view/
.
Below is a shipping address renderer’s general view:
define([
'ko',
'uiComponent',
'Magento_Checkout/js/action/select-shipping-address',
'Magento_Checkout/js/model/quote'
], function(ko, Component, selectShippingAddressAction, quote) {
'use strict';
return Component.extend({
defaults: {
template: '%path to your template%'
},
initProperties: function () {
this._super();
this.isSelected = ko.computed(function() {
var isSelected = false;
var shippingAddress = quote.shippingAddress();
if (shippingAddress) {
isSelected = shippingAddress.getKey() == this.address().getKey();
}
return isSelected;
}, this);
return this;
},
/** Set selected customer shipping address */
selectAddress: function() {
selectShippingAddressAction(this.address());
},
/** additional logic required for this renderer **/
});
});
Step 2: Create template for shipping address renderer
In this step, you need to create a <your_module_dir>/view/frontend/web/template/<your_template>.html
file in your custom module directory. You can use Knockout JS syntax for your template.
A button which is used for setting the address for shipping should be included in the template.
The code from the default template can be used: app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html.
Step 3: Create JS model for shipping rate processor
Retrieving the shipping rates which are available for the given shipping address is responsible by a shipping rate processor.
Create a component’s .js file
for the processor in your custom module directory. This file have to be located under the directory <your_module_dir>/view/frontend/web/js/model/
In here, the URL which is used to calculate the shipping rates for your custom address type needs to be specified.
Down here is a shipping rate processor code’s sample:
define(
[
'Magento_Checkout/js/model/quote',
'Magento_Checkout/js/model/shipping-service',
'Magento_Checkout/js/model/shipping-rate-registry',
'magento/storage',
'Magento_Checkout/js/model/error-processor',
// additional dependencies
],
function (quote, shippingService, rateRegistry, storage, errorProcessor, ...) {
'use strict';
return {
getRates: function(address) {
var cache = rateRegistry.get(address.getKey());
if (cache) {
shippingService.setShippingRates(cache);
} else {
shippingService.isLoading(true);
storage.post(
%URL for shipping rate estimation%,
JSON.stringify({
%address parameters%
}),
false
).done(
function (result) {
rateRegistry.set(address.getKey(), result);
shippingService.setShippingRates(result);
}
).fail(
function (response) {
shippingService.setShippingRates([]);
errorProcessor.process(response);
}
).always(
function () {
shippingService.isLoading(false);
}
);
}
}
};
}
);
Step 4: Create JS model for shipping address saving processor
This processor handles sending the shipping address and the selected rate to the server.
In this step, you need to create the component’s .js
file for the processor in your custom module directory.
Here is a shipping rate processor code’s sample:
define(
[
'Magento_Checkout/js/model/quote',
'Magento_Checkout/js/model/resource-url-manager',
'mage/storage',
'Magento_Checkout/js/model/payment-service',
'Magento_Checkout/js/model/error-processor',
'Magento_Checkout/js/model/payment/method-converter'
],
function (quote, resourceUrlManager, storage, paymentService, errorProcessor, methodConverter) {
'use strict';
return {
saveShippingInformation: function() {
var shippingAddress = {},
payload;
shippingAddress.extension_attributes = {
%address extension attributes%
};
payload = {
addressInformation: {
shipping_address: shippingAddress,
shipping_method_code: quote.shippingMethod().method_code,
shipping_carrier_code: quote.shippingMethod().carrier_code
}
};
return storage.post(
resourceUrlManager.getUrlForSetShippingInformation(quote),
JSON.stringify(payload)
).done(
function (response) {
paymentService.setPaymentMethods(methodConverter(response.payment_methods));
quote.setTotals(response.totals)
}
).fail(
function (response) {
errorProcessor.process(response);
}
);
}
}
}
);
Step 5: Create JS component registering processors
A .js
UI component that registers the rate processor and the saving processor need to be created in your custom module directory. And this component need to be located under the <your_module_dir>/view/frontend/web/js/view/
directory.
The content of the file must be similar to this:
define(
[
'uiComponent',
'Magento_Checkout/js/model/shipping-rate-service',
%custom shipping rate processor%,
'Magento_Checkout/js/model/shipping-save-processor',
%custom shipping save processor%
],
function (
Component,
shippingRateService,
customShippingRateProcessor,
shippingSaveProcessor,
customShippingSaveProcessor
) {
'use strict';
/** Register rate processor */
shippingRateService.registerProcessor(%address type%, customShippingRateProcessor);
/** Register save shipping address processor */
shippingSaveProcessor.registerProcessor(%address type%, custormShippingSaveProcessor);
/** Add view logic here if needed */
return Component.extend({});
}
);
Step 6: Declare new components in checkout page layout
A <your_module_dir>/view/frontend/layout/checkout_index_index.xml
file need to be created in your custom module directory. Then add the following code in that file:
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="checkout.root">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="checkout" xsi:type="array">
<item name="children" xsi:type="array">
<item name="steps" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shipping-step" xsi:type="array">
<item name="children" xsi:type="array">
<!-- Declare the component that registers the shipping address and rates processors -->
<item name="custom-address-provider" xsi:type="array">
<item name="component" xsi:type="string">%component that registers address/rate processors%</item>
</item>
<!-- Declare the component that renders the shipping address -->
<item name="shippingAddress" xsi:type="array">
<item name="children" xsi:type="array">
<item name="rendererTemplates" xsi:type="array">
<item name="%address type%" xsi:type="array">
<item name="component" xsi:type="string">%address renderer JS component%</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
Step 7: Add shipping address renderer to Ship-To
block
On the Review and Payment Information step, the shipping address is shown in the Ship-To section, which would ensure that everything is set correctly.
If you want the address type to be shown in here also, you need to render it by creating a .html
template. And declare in the corresponding location in the layout.
Add template for displaying address in Ship-To section
You need to create a <your_module_dir>/view/frontend/web/template/<your_template>.html
file in your custom module directory. You can use Knockout JS syntax for your template.
The code from the default template can be used: app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html.
Declare address to be used in Ship-To section in layout
Add the following code into your <your_module_dir>/view/frontend/layout/checkout_index_index.xml
file:
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<block class="Magento\Checkout\Block\Onepage" name="checkout.root" template="onepage.phtml" cacheable="false">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="sidebar" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shipping-information" xsi:type="array">
<item name="children" xsi:type="array">
<item name="ship-to" xsi:type="array">
<item name="rendererTemplates" xsi:type="array">
<item name="%address type%" xsi:type="array">
<item name="component" xsi:type="string">uiComponent</item>
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">%custom template%</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</block>
</referenceContainer>
</body>
</page>
Conclusion
Above I have just provided you with seven steps to help you custom shipping address template in checkout steps, hope this instruction is helpful for you. If you have further questions or new ideas, feel free to leave a comment below.
Enjoyed the tutorial? Spread it to your friends!