Magento 2 : Add custom script just after head tag
Solution 1
I am not sure if this is the correct way or not, but I have got a lead.
By default magento 2 usees the root.phtml
file to setup head
content accordingly, which is located in vendor/magento/module-theme/view/base/templates/root.phtml
(if it has not been overridden).
Here, the $requireJs
variable is loaded first in the head block. The $requireJs
variable is defined in the render
method inside Page
class -which is located in vendor/magento/framework/view/Result/Page.php
.
In this file, $requireJs
contains the require.js
block. And the require.js
block is defined in vendor/Magento/module-theme/view/frontend/layout/default.xml
:
<block name="require.js" class="Magento\Framework\View\Element\Template" template="Magento_Theme::page/js/require_js.phtml" />
Solution
1) Copy require_js.phtml
from vendor/magento/module-theme/view/frontend/templates/page/js
to your theme app/design/frontend/{VENDOR}/{THEME_NAME}/Magento_Theme/templates/page/js/
2) Now you can add your script like this:
<script>
console.log("I'm loaded!");
var require = {
"baseUrl": "<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('/') ?>"
};
</script>
UPDATE (Using Module)
Overriding the require.js
block is not an elegant solution. if anyone has a good solution please answer. For now edit your layout xml:
<referenceBlock name="require.js">
<action method="setTemplate">
<argument name="template" xsi:type="string">Custom_Module::success/head.phtml</argument>
</action>
</referenceBlock>
and inside success/head.phtml
add your code:
<script>
console.log("I'm loaded!");
var require = {
"baseUrl": "<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('/') ?>"
};
</script>
Solution 2
I found a simple way of doing it that seems very reasonable, because it uses existing features in the adminhtml
theme without any need to override/intercept anything.
Background
Like @sanchit-gupta mentioned, the root.phtml
template is used as the basis to render both the frontend
and adminhtml
areas, and so is the associated class \Magento\Framework\View\Result\Page
, which always looks for a block named head.additional
before rendering.
This block exists in the frontend
layouts by default, but unfortunately it doesn't exist in the adminhtml
layout.
Solution
With that in mind, the current best way (as of 2.3.x) to add inline <scripts>
to the adminhtml
's <head>
section is to add any head.additional
block: it will be automatically rendered by the framework. It either has to be a ListText
block so that it renders all it's children automatically, or a Template
with a specified template file. I actually chose too nest my actual block inside the ListText
block just to keep the same mechanism available as in the frontend
area (i.e. for compatibility with other plugins that might be doing the same).
Example
In your custom module or theme, add a layout update that inserts the following block into the body
of the page layout (which is just to do it the same way as it's done in Magento 2 core for the frontend
area):
<body>
<block class="Magento\Framework\View\Element\Text\ListText" name="head.additional">
<block name="your_block" class="Magento\Framework\View\Element\Template" template="Your_Module::your/template.phtml" />
</block>
</body>
Done! Your template will render inside <head></head>
– without any awkward overrides or "hacks".
What's more, if other modules also reference head.additional
in the adminhtml
area, they will be compatible with your code.
Related videos on Youtube
Sandip Dutt
Updated on June 08, 2022Comments
-
Sandip Dutt almost 2 years
i want to add custom script just after the start of head tag.
like.
<head> <script>console.log("I'm loaded!");</script>
i tried to add code in default_head_blocks.xml
<referenceContainer name="head.additional"> <block class="Custom\Module\Block\Success" template="Custom_Module::success/head.phtml"/> </referenceContainer>
=> output :
<script>console.log("I'm loaded!");</script> </head>
this code are using add script before the end of head tag.
Please check Below code
Block => Custom/Module/Block/Onepage/Success.php
namespace Custom\Module\Block\Onepage; use Magento\Framework\View\Element\Template; class Success extends \Magento\Checkout\Block\Onepage\Success { public function getOrder() { $objectManager =\Magento\Framework\App\ObjectManager::getInstance(); $helper = $objectManager->get('Custom\Module\Helper\Data'); $lastOrderId = $this->getOrderId(); if (empty($lastOrderId)) { return null; } $orderData = $objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId($this->getOrderId()); return $orderData; } }
Helper => Custom\Module\Helper\Data.php
namespace Custom\Module\Helper; class Data extends \Magento\Framework\App\Helper\AbstractHelper { /** * @param \Magento\Framework\App\Helper\Context $context */ protected $_request; public function __construct( \Magento\Framework\App\Helper\Context $context, \Magento\Framework\App\Request\Http $request ) { $this->_request = $request; parent::__construct($context); } public function getConfigValue($value = '') { return $this->scopeConfig ->getValue($value,\Magento\Store\Model\ScopeInterface::SCOPE_STORE); } public function getTemplate() { if ($this->getConfigValue('custom_general/general/active') == 1) { $template = 'Custom_Module::checkout/success.phtml'; } else { $template = 'Magento_Checkout::success.phtml'; } return $template; } }
di.xml => etc\di.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../vendor/magento/framework/ObjectManager/etc/config.xsd"> <preference for="Magento\Checkout\Block\Onepage\Success" type="Custom\Module\Block\Onepage\Success"/> </config>
Layout Xml => Custom/Module/view/frontend/layout/default.xml
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="require.js"> <action method="setTemplate"> <argument name="template" xsi:type="string">Custom_Module::success/head.phtml</argument> </action> </referenceBlock> </body> </page>
Template => Custom/Module/view/frontend/templates/success/head.phtml
<script> console.log("I'm loaded!"); </script>
Please help me and solve this issue
Thanks in advance.
-
Sandip Dutt over 6 yearsThanks for the replay,
-
Sandip Dutt over 6 yearsbut i don't want to add script in require_js.phtml and root.phtml because i didn't added custom theme , it's my custom module so.
-
Sanchit Gupta over 6 years@SandipDutt ! please check the updated answer if it helps you or not?
-
Sanchit Gupta over 6 years@SandipDutt could you please share you code for better understanding?
-
Sandip Dutt over 6 yearsOk but when i added your solution in default.xml it getting error like invalid method Magento\Framework\View\Element\Template for action set template can you share your code here?
-
Sanchit Gupta over 6 years@SandipDutt Nice! Happy Coding :)