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:
{{store url=""}}
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:
<a href="{{store url='men/tops-men.html'}}">Men's Tops</a>
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
<a href="{{store direct_url='contact'}}">Contact Us</a>
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.
Implementing Category Links in Footer Static Blocks
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:
<div class="footer-links">
<h3>Shop Our Collections</h3>
<ul>
<li><a href="{{store url='new-arrivals'}}">New Arrivals</a></li>
<li><a href="{{store url='sale'}}">Clearance Sale</a></li>
<li><a href="{{store url='gear/bags'}}">Travel Bags</a></li>
</ul>
</div>
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:
<img src="{{media url='wysiwyg/promo-banner.jpg'}}" alt="Summer Sale" />
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:
- Cache: Magento heavily caches CMS blocks. After updating a block with a new directive, always flush the Magento cache:
php bin/magento cache:flush. - 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.
- 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.
How do I link to a specific product?
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.