Important

You are browsing upcoming documentation for version 7.1 of OroCommerce, scheduled for release in 2027. Read the documentation for the latest LTS version to get up-to-date information.

See our Release Process documentation for more information on the currently supported and upcoming releases.

How to Add Third-Party Scripts 

Use this article to learn about the supported methods for adding marketing, analytics, advertising, and support scripts to the OroCommerce storefront and choose the appropriate method for your use case.

These tools, such as chat widgets, tracking pixels, and A/B testing platforms, are usually integrated into the storefront by adding a JavaScript snippet to every page or to specific pages.

Important

Third-party scripts typically set non-essential cookies. In many jurisdictions, these cookies require prior, informed, opt-in visitor consent. Before adding a script, review the Cookie Consent concept guide and ensure that the script loads only after the customer user provides the required consent. See the Load a Script Only After Cookie Consent section below.

Note

The examples use the following placeholders:

  • {BundleName} — the path to your bundle in the src folder (for example, Custom/Bundle/ThemeBundle).

  • {bundle_name} — the name of the folder under public/bundles/ where the assets of your bundle are published. The name is based on the bundle class name without the Bundle suffix and is written in lowercase. For example, use customtheme for CustomThemeBundle.

  • {theme_name} — the identifier of your storefront theme.

Add an External Script 

To add a script to every storefront page, place the layout update directly in the theme folder. The example below adds an asynchronous external script to the <head>:

src/{BundleName}/Resources/views/layouts/{theme_name}/analytics_scripts.yml 
 layout:
     actions:
         - '@add':
             id: custom_analytics_script
             parentId: head
             blockType: script
             options:
                 src: 'https://analytics.example.com/tracker.js'
                 async: true

For scripts that are not required for the initial page render, set parentId to body. This appends the block after the main content and before the closing </body> tag, allowing the page to become visible without waiting for the script to load:

src/{BundleName}/Resources/views/layouts/{theme_name}/support_widget.yml 
 layout:
     actions:
         - '@add':
             id: custom_support_widget_script
             parentId: body
             blockType: script
             options:
                 src: 'https://widget.example.com/support.js'
                 defer: true

Add a Script as a Twig Block 

For inline snippets, keep the JavaScript code in a Twig template instead of the YAML file. Add the container block and render the snippet in the corresponding Twig block. This approach keeps the YAML file concise, provides JavaScript code highlighting in the editor, enables you to pass backend values to the snippet, and matches the patterns used by the built-in Google Tag Manager integration to embed its own scripts. The following example configures a chat widget with the current storefront locale and appends its loader to the end of <body>:

src/{BundleName}/Resources/views/layouts/{theme_name}/chat_widget.yml 
 layout:
     actions:
         - '@setBlockTheme':
             themes: 'chat_widget.html.twig'
         - '@add':
             id: custom_chat_widget_script
             parentId: body
             blockType: container
src/{BundleName}/Resources/views/layouts/{theme_name}/chat_widget.html.twig 
 {% block _custom_chat_widget_script_widget %}
     <script>
         window.exampleChatSettings = {
             workspace: 'custom-storefront',
             locale: '{{ app.request.locale }}'
         };

         var chatLoader = document.createElement('script');
         chatLoader.src = 'https://widget.example-chat.com/loader.js';
         chatLoader.async = true;
         document.head.appendChild(chatLoader);
     </script>
 {% endblock %}

The Twig block name is built from the block id. For example, if the block ID is custom_chat_widget_script, the template must define the _custom_chat_widget_script_widget block. A themes value without a path is resolved relative to the folder that contains the layout update file. For more information about block themes and block naming conventions, see Templates.

Note

If the snippet only loads an external file and does not require configuration, do not use a Twig block. Use the script block type with the src and async options, as described in the Add an External Script section. The script block type also supports inline code through its content option. Use this option when the snippet is short or comes from a layout data provider.

Add a Script to Specific Pages Only 

To load a script only on specific pages, place the layout update in a folder named after the corresponding route. A route is the internal name under which a page is registered in the application.

For example, product view pages use the oro_product_frontend_product_view route. A layout update placed in a folder with the same name loads the script only on product view pages:

src/{BundleName}/Resources/views/layouts/{theme_name}/oro_product_frontend_product_view/product_scripts.yml 
 layout:
     actions:
         - '@add':
             id: custom_product_review_widget
             parentId: body
             blockType: script
             options:
                 src: 'https://reviews.example.com/widget.js'
                 defer: true

Note

Layout options support expressions. For example, you can build the src URL from the current theme or pass backend data into the inline content via layout data providers.

The Script Layout Block Type 

The examples above use the script layout block type, added to a page with a regular layout update in your theme. The block supports the following options:

Option

Default

Description

src

null

URL of an external script. When set, the content option is ignored.

content

''

Inline JavaScript code, rendered inside the <script> tag.

async

false

Adds the async attribute.

defer

false

Adds the defer attribute.

type

text/javascript

Value of the type attribute.

crossorigin

null

Value of the crossorigin attribute.

The base page layout provides two insertion points:

  • head — the <head> element. Use it for scripts that must load before the page renders.

  • body — the <body> element. The blocks appended to it render before the closing </body> tag, after the main content.