In Magento 2 development, you will frequently encounter scenarios where you have an ISO country code (like 'US', 'GB', or 'FR') but need to display the full, human-readable country name. This is particularly common when customizing order transactional emails, building custom shipping modules, or generating PDF invoices. While the database often stores the two-letter country_id, providing a localized country name is essential for a professional user experience.
In this guide, you will learn multiple ways to get the country name from a country code in Magento 2, ranging from the classic Model Factory approach to the modern Service Contract method recommended by Adobe Commerce standards.
Understanding Country Data in Magento 2
Magento 2 manages geographical data through the Magento_Directory module. Country information is stored in the directory_country table, and localized names are typically handled via the directory_country_name table. When you retrieve an order address, the getCountryId() method returns the 2-letter ISO code. To transform this into a full name, you must interact with Magento's directory models or APIs.
Method 1: Using the CountryFactory (The Direct Approach)
The most straightforward way to retrieve a country name is by using the Magento\Directory\Model\CountryFactory. This method is highly effective for quick implementations in custom blocks or helpers.
First, you need to inject the CountryFactory into your class constructor:
namespace Vendor\Module\Block;
use Magento\Directory\Model\CountryFactory;
use Magento\Framework\View\Element\Template;
class CountryInfo extends Template
{
protected $_countryFactory;
public function __construct(
Template\Context $context,
CountryFactory $countryFactory,
array $data = []
) {
$this->_countryFactory = $countryFactory;
parent::__construct($context, $data);
}
/**
* Get Country Name by Code
*
* @param string $countryCode
* @return string
*/
public function getCountryName($countryCode)
{
$country = $this->_countryFactory->create()->loadByCode($countryCode);
return $country->getName();
}
}
Once your block is set up, you can call the method from your .phtml template file like this:
<?= $block->getCountryName($countryCode); ?>
While this method is simple, it relies on loading the full model, which may be slightly heavier than necessary if you are working with large collections of data.
Method 2: Using CountryInformationAcquirerInterface (The Recommended Way)
If you are following Magento 2 best practices, you should use Service Contracts. The Magento\Directory\Api\CountryInformationAcquirerInterface is the modern API-based approach to fetching directory information. This is cleaner, more testable, and ensures your code remains compatible with future Magento updates.
This interface provides a getCountryInfo method that returns a data object containing both English and localized names.
/** @var \Magento\Directory\Api\CountryInformationAcquirerInterface $countryInformationAcquirer */
try {
$countryInfo = $this->countryInformationAcquirer->getCountryInfo($countryCode);
// Get the name in English
$englishName = $countryInfo->getFullNameEnglish();
// Get the name based on the current store locale
$localName = $countryInfo->getFullNameLocale();
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
// Handle error if country code is invalid
}
This approach is superior because it gives you granular control over whether you want the English name or the translated name based on the user's current locale.
Practical Example: Displaying Country Names in Custom Order Views
Let’s look at a comprehensive example. Suppose you are creating a custom print view for an order and need to format the billing and shipping addresses including the full country names.
In the following Block class, we use the CountryInformationAcquirerInterface to process order data retrieved from the OrderRepositoryInterface.
namespace Equaltrue\Orderprint\Block\Order;
use Magento\Backend\Block\Template\Context;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Registry;
use Magento\Framework\View\Element\Template;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Directory\Api\CountryInformationAcquirerInterface;
class Print extends Template
{
protected $_coreRegistry;
protected $orderRepository;
protected $countryInformationAcquirerInterface;
public function __construct(
CountryInformationAcquirerInterface $countryInformationAcquirerInterface,
OrderRepositoryInterface $orderRepository,
Context $context,
Registry $coreRegistry,
array $data = []
) {
$this->orderRepository = $orderRepository;
$this->countryInformationAcquirerInterface = $countryInformationAcquirerInterface;
$this->_coreRegistry = $coreRegistry;
parent::__construct($context, $data);
}
public function getOrderData()
{
$orderId = $this->getRequest()->getParam('order_id', 0);
$order = $this->orderRepository->get($orderId);
// Process Billing Address
$billingAddress = $order->getBillingAddress();
$countryIdBilling = $billingAddress->getCountryId();
$countryNameBilling = $this->getCountryName($countryIdBilling);
// Process Shipping Address
$shippingAddress = $order->getShippingAddress();
$countryIdShipping = $shippingAddress->getCountryId();
$countryNameShipping = $this->getCountryName($countryIdShipping);
return [
"billing_country" => $countryNameBilling,
"shipping_country" => $countryNameShipping
];
}
public function getCountryName($countryCode, $type = "local")
{
try {
$data = $this->countryInformationAcquirerInterface->getCountryInfo($countryCode);
return ($type == "local") ? $data->getFullNameLocale() : $data->getFullNameEnglish();
} catch (NoSuchEntityException $e) {
return $countryCode; // Fallback to code if not found
}
}
}
Why use NoSuchEntityException?
When working with the Directory API, it is vital to wrap your call in a try-catch block. If a developer or a third-party extension passes an invalid or non-existent country code to the getCountryInfo method, Magento will throw a NoSuchEntityException. Catching this allows you to provide a fallback (like returning the original code) instead of crashing the page.
Frequently Asked Questions
How do I get the country name in a specific language other than the current locale?
To get a country name in a specific language, you generally need to emulate the store or use the Magento\Framework\Translate functionality. However, the getFullNameLocale() method is usually sufficient as it automatically pulls from the translation strings defined in the active locale's CSV files.
Is there a performance difference between the Factory and the API?
Using the CountryInformationAcquirerInterface is generally preferred for architectural consistency. While the performance difference is negligible for a single lookup, the API approach is cleaner as it returns a Data Transfer Object (DTO) rather than a heavy Model instance.
Can I use these methods in a CLI script or Cron job?
Yes. As long as you use Dependency Injection to inject the CountryInformationAcquirerInterface or CountryFactory into your class, these methods will work in any Magento 2 context, including Cron jobs, CLI commands, and API endpoints.
Wrapping Up
Retrieving the full country name from a country code in Magento 2 can be achieved through both traditional models and modern service contracts. For most use cases, the CountryInformationAcquirerInterface is the best choice because it supports localization and adheres to Magento's service-oriented architecture.
Key Takeaways:
- Use CountryFactory for quick, legacy-style implementations.
- Use CountryInformationAcquirerInterface for modern, API-compliant code.
- Always wrap API calls in a try-catch block to handle NoSuchEntityException gracefully.
- Choose between getFullNameEnglish() and getFullNameLocale() based on your specific display requirements.