When managing a Magento 2 store, one of the most common tasks for administrators and developers is creating links within CMS blocks and pages. Whether you are building a custom footer, a promotional banner, or a sidebar navigation menu, hardcoding URLs is a practice you should strictly avoid. Hardcoded URLs create significant technical debt, especially when migrating from a staging environment to production or when managing a multi-store setup.

In this guide, you will learn how to use Magento 2's built-in template directives to dynamically fetch the base URL of the current store. This ensures your links remain functional regardless of domain changes or store view configurations.

Why Use Dynamic URLs in Magento 2?

Before diving into the syntax, it is important to understand why dynamic URLs are the standard in Magento development. If you hardcode a link like https://mystore.com/about-us into a static block, that link will break if you ever change your domain or if you have a multi-language site (e.g., https://mystore.com/fr/about-us).

By using the {{store}} directive, Magento automatically resolves the correct URL based on the user's current store view. This is handled by the Magento rendering engine, specifically the template filter classes, which parse these curly-brace placeholders before the content is delivered to the browser.

Using the Store URL Directive

The most straightforward way to retrieve the base URL of your current store within a CMS block or page is by using the store tag. This tag is highly versatile and can be used in several ways.

1. Linking to the Homepage (Base URL)

To simply output the base URL of the current store, use the following syntax:

<?php
namespace Custom\Module\Controller\Index;

use Magento\Framework\App\Action\Context;
use Magento\Framework\App\Request\Http;

class Index extends \Magento\Framework\App\Action\Action
{
    /**
     * @var Http
     */
    protected $request;

    /**
     * @param Context $context
     * @param Http $request
     */
    public function __construct(
        Context $context,
        Http $request
    ) {
        parent::__construct($context);
        $this->request = $request;
    }

    public function execute()
    {
        // Retrieve individual routing components
        $moduleName     = $this->request->getModuleName();
        $controllerName = $this->request->getControllerName();
        $actionName     = $this->request->getActionName();
        $routeName      = $this->request->getRouteName();

        // Log or display the results
        echo "Module: " . $moduleName . "<br/>";
        echo "Controller: " . $controllerName . "<br/>";
        echo "Action: " . $actionName . "<br/>";
        echo "Route: " . $routeName . "<br/>";

        $this->_view->loadLayout();
        $this->_view->renderLayout();
    }
}

When rendered, this will output the full URL of the store homepage, including the protocol (HTTP/HTTPS) and any store codes if they are enabled in your configuration.

2. Linking to Specific Categories or Pages

If you want to link to a specific category or a CMS page, you can pass the URL key (identifier) directly into the url parameter. For example, if you are displaying category names in the footer and want them to link to their respective pages, you would use:

$fullActionName = $this->request->getFullActionName();

This approach ensures that if your store is moved to a subdirectory or a different domain, the link structure remains intact.

Using the direct_url Parameter

While the url parameter is the most common, Magento also supports the direct_url parameter. This is particularly useful when you want to point to a specific path without Magento's internal URL processing adding extra suffixes or parameters.

The Syntax for direct_url

$controllerName = $this->getRequest()->getControllerName();
$actionName = $this->getRequest()->getActionName();
$routeName = $this->getRequest()->getRouteName();
$moduleName = $this->getRequest()->getModuleName();

url vs. direct_url: Which Should You Use?

  • Use url: When you want Magento to handle the pathing according to standard routing rules. This is generally the safest bet for categories and products.
  • Use direct_url: When you have a specific custom route or a simple CMS identifier that you want to link to directly without any modification by the store's URL rewrite system.

A frequent use case for these directives is creating a "Quick Links" section in the footer. Developers often use a static block to manage these links so that non-technical administrators can update them easily.

Here is how you would structure a clean, dynamic list of category links in a Magento 2 static block:

// Returns the full module identifier, e.g., "Magento_Customer"
echo $this->request->getControllerModule();

Handling Media and Images

While this guide focuses on page URLs, it is worth noting that you should also use dynamic directives for images within your static blocks. Hardcoding image paths from the /pub/media/ folder is a common mistake. Instead, use the media directive:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$request = $objectManager->get('\Magento\Framework\App\Request\Http');
echo $request->getFullActionName();

Just like the store directive, this ensures your images load correctly across different environments (local, staging, production).

Troubleshooting Common Issues

If you find that your tags are appearing as plain text on the frontend instead of being converted into URLs, check the following:

  1. Cache: Magento heavily caches CMS blocks. After updating a block with a new directive, always flush the Magento cache: php bin/magento cache:flush.
  2. WYSIWYG Editor: Sometimes, the Admin WYSIWYG editor can escape characters or add hidden HTML tags inside your curly braces. It is always safer to toggle the editor off and paste the code directly into the raw HTML view.
  3. Syntax Errors: Ensure you are using straight quotes (" or ') rather than curly "smart quotes" often introduced by word processors.

Frequently Asked Questions

Can I use these directives in PHTML files?

No, these curly-brace directives are specific to the CMS content filter. In a .phtml template file, you should use PHP to get the URL, such as $block->getUrl('path/to/page') or via the StoreManagerInterface.

Does this work for multi-language stores?

Yes. This is the primary benefit. If you have a store view for English (/en/) and one for French (/fr/), {{store url='about'}} will automatically resolve to the correct path for the specific store view the customer is currently browsing.

To link to a product, you should use the product's URL key. For example: {{store url='awesome-product-sku.html'}}. Note that if your URL structure changes (e.g., adding or removing .html suffixes), you must ensure the string in the directive matches your current configuration.

Wrapping Up

Mastering the {{store}} directive is a fundamental skill for any Magento 2 developer or content manager. It ensures your store remains flexible, scalable, and easy to maintain. By utilizing {{store url=""}} and {{store direct_url=""}}, you can create a seamless navigation experience that works perfectly across multiple domains and environments. Always remember to test your links after deployment and keep your cache clear to see the changes immediately.