How to Customize Shipping Address Template in Magento 2
Vinh Jacker | 12-18-2024
Customizing the shipping address template in Magento 2 allows store owners to align the checkout process with their branding and enhance user experience. This guide provides a step-by-step approach to modifying the shipping address template effectively.
Why Need to Customize the Shipping Address Template in Magento 2?
Customizing the shipping address template in Magento 2 offers several advantages that can significantly enhance your store’s functionality and user experience. Here’s why you might want to customize this template:
- Enhanced Branding: Personalizing the template ensures it aligns with your store’s branding, creating a cohesive look and feel across your website.
- Improved User Experience: Simplify the checkout process by rearranging fields or adding helpful instructions, making it more intuitive for customers.
- Meet Specific Business Needs: Add or remove fields to accommodate unique business requirements, such as capturing specific customer information relevant to your operations.
- Streamlined Data Collection: Ensure the shipping address template collects all the necessary data while removing irrelevant fields to avoid confusion or delays in order processing.
How to customize shipping address template in 7 steps
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. 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 a 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 that are available for the given shipping address is the responsibility of 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/
Here, the URL that 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 rated processor and the saving processor needs to be created in your custom module directory. This component needs 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 needs 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
In the Review and Payment Information step, the shipping address is shown in the Ship-To section, which ensures that everything is set correctly.
If you want the address type to be shown here, you also 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>
Best Practices for Customizing Shipping Address Template in Magento 2
When customizing the shipping address template in Magento 2, it’s essential to follow best practices to ensure your changes are effective, maintainable, and do not disrupt your store’s functionality. Below are some key best practices:
- Use a Custom Module or Child Theme: Avoid editing core Magento files directly. Use a custom module or a child theme to make your changes upgrade-safe.
- Backup Your Store: Before implementing any customization, always create a backup of your Magento store to safeguard your data and configurations.
- Test in a Staging Environment: Perform all changes and testing in a staging or development environment to avoid impacting your live store during the customization process.
- Clear Cache Regularly: Magento relies heavily on caching. Always clear your store’s cache after making changes to ensure your customizations take effect properly.
- Follow Magento Coding Standards: Adhere to Magento’s coding practices and standards to ensure your changes integrate seamlessly with the platform.
Conclusion
Customizing the shipping address template in Magento 2 is a powerful way to enhance your store’s checkout experience. By creating a custom module or child theme, you can make these changes in a way that is safe and maintainable. Follow the steps outlined in this guide to achieve a personalized and user-friendly checkout process.