Loading customer data is one of the most common tasks in Magento 2 development — for account pages, custom emails, integrations, or admin tools. This guide covers both lookups: how to load a customer by ID and how to load a customer by email, each with three approaches (API repository, factory, and object manager). The repository method is the recommended one for real modules; the others are shown for completeness.
How to Load a Customer by ID in Magento 2
Using the Customer Repository (Recommended)
Inject CustomerRepositoryInterface and call getById(). Here it's wrapped in a block method so you can call it from a template:
<?php
namespace Mageants\Blog\Block;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
use Magento\Customer\Api\CustomerRepositoryInterface;
class CustomerInfo extends Template
{
protected $customerRepository;
public function __construct(
Context $context,
CustomerRepositoryInterface $customerRepository,
array $data = []
) {
$this->customerRepository = $customerRepository;
parent::__construct($context, $data);
}
public function getCustomerData($id)
{
return $this->customerRepository->getById($id);
}
}
|
Then call it from your .phtml template:
<?php $customerId = 1; // pass a dynamic customer ID $customer = $block->getCustomerData($customerId); echo $block->escapeHtml($customer->getFirstname()); // first name echo $block->escapeHtml($customer->getLastname()); // last name echo $block->escapeHtml($customer->getEmail()); // email |
Using the Factory Method
The customer model's load() works too. Direct model loading is discouraged in new code in favour of the repository, but it's still widely seen:
<?php
namespace Mageants\Blog\Block;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
use Magento\Customer\Model\CustomerFactory;
class CustomerInfo extends Template
{
protected $customerFactory;
public function __construct(
Context $context,
CustomerFactory $customerFactory,
array $data = []
) {
$this->customerFactory = $customerFactory;
parent::__construct($context, $data);
}
public function getCustomerData()
{
$customerId = 1; // pass a dynamic customer ID
$customer = $this->customerFactory->create()->load($customerId);
return $customer->getFirstname();
}
}
|
Using the Object Manager (Quick Tests Only)
Fine for a throwaway test, never for module code — always inject dependencies instead:
<?php $customerId = 1; $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $customer = $objectManager->create(\Magento\Customer\Model\Customer::class)->load($customerId); echo $customer->getFirstname(); |
How to Load a Customer by Email in Magento 2
Customers are scoped per website, so loading by email needs a website ID as well as the email address.
Using the Customer Repository (Recommended)
Inject both CustomerRepositoryInterface and StoreManagerInterface, then call get() with the email and website ID:
<?php
namespace Mageants\Blog\Block;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Store\Model\StoreManagerInterface;
class CustomerInfo extends Template
{
protected $customerRepository;
protected $storeManager;
public function __construct(
Context $context,
CustomerRepositoryInterface $customerRepository,
StoreManagerInterface $storeManager,
array $data = []
) {
$this->customerRepository = $customerRepository;
$this->storeManager = $storeManager;
parent::__construct($context, $data);
}
public function getCustomerData($customerEmail)
{
$websiteId = $this->storeManager->getStore()->getWebsiteId();
return $this->customerRepository->get($customerEmail, $websiteId);
}
}
|
Call it from your .phtml:
<?php $customerEmail = 'roni_cost@example.com'; // pass a dynamic email $customer = $block->getCustomerData($customerEmail); echo $block->escapeHtml($customer->getId()); // customer ID echo $block->escapeHtml($customer->getFirstname()); // first name echo $block->escapeHtml($customer->getLastname()); // last name |
Using the Factory Method
The model exposes loadByEmail(), but you must set the website ID first:
<?php
namespace Mageants\Blog\Block;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
use Magento\Customer\Model\CustomerFactory;
use Magento\Store\Model\StoreManagerInterface;
class CustomerInfo extends Template
{
protected $customerFactory;
protected $storeManager;
public function __construct(
Context $context,
CustomerFactory $customerFactory,
StoreManagerInterface $storeManager,
array $data = []
) {
$this->customerFactory = $customerFactory;
$this->storeManager = $storeManager;
parent::__construct($context, $data);
}
public function getCustomerData()
{
$customerEmail = 'roni_cost@example.com'; // pass a dynamic email
$websiteId = $this->storeManager->getStore()->getWebsiteId();
$customer = $this->customerFactory->create()
->setWebsiteId($websiteId)
->loadByEmail($customerEmail);
return $customer->getFirstname();
}
}
|
Using the Object Manager (Quick Tests Only)
<?php $customerEmail = 'roni_cost@example.com'; $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $customer = $objectManager->create(\Magento\Customer\Model\Customer::class); $customer->setWebsiteId(1); $customer->loadByEmail($customerEmail); echo $customer->getFirstname(); |
Working with orders too? See our detailed post on how to load an order by ID in Magento 2 programmatically.
Conclusion
Loading a customer in Magento 2 comes down to two rules: prefer CustomerRepositoryInterface (getById for ID, get for email) over direct model loading in production code, and remember that email lookups are website-scoped, so always pass the website ID. The factory and object-manager routes work, but keep the latter to quick tests only.
Need custom customer data handling, integrations, or admin tools built the right way? You can hire Magento 2 developers from MageAnts to handle it end to end. Any trouble with the code above? Feel free to contact us.