The normal way to add a stylesheet to a page is to call \Magento\Framework\View\Page\Config::addPageAsset()
Here is an example: How to load JavaScript or stylesheet conditionally depends on backend config settings?
But sometimes the normal way is not available because the layout has already been built (the \Magento\Framework\View\Layout\Builder::build()
has already been finished).
I have found 2 solutions of the problem.
Solution 1
If the layout is already built but HTML document is not rendered yet then we can generate <link>
tag manually and insert it to the HTML document.
A <link>
tag is valid inside the <body>
tag in HTML 5.
We can use the \Magento\Framework\View\Asset\File::getUrl()
method to get an asset url:
/**
* @param string $asset
* @return string
*/
function getAssetUrl($asset) {
/** @var \Magento\Framework\ObjectManagerInterface $om */
$om = \Magento\Framework\App\ObjectManager::getInstance();
/** @var \Magento\Framework\View\Asset\Repository $assetRepository */
$assetRepository = $om->get('Magento\Framework\View\Asset\Repository');
return $assetRepository->createAsset($asset)->getUrl();
}
For example:
getAssetUrl('Dfe_Markdown::simple-mde/main.css');
Solution 2
If the decision whether to load the asset need to be made interactively on the browser side then we can get the asset url using the Solution 1 and then pass the asset url to a JavaScript component as a parameter.
Then the JavaScript component can generate a <link>
tag interactively to load the asset:
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = url;
document.getElementsByTagName("head")[0].appendChild(link);
It is not a simple way but it works. Waiting for a standard and more simplier way: