Search by

chatixy / module-chat

JanchaLV

Chatixy AI Support Agent - add the Chatixy AI support agent to your Magento storefront, no code.

Package info

github.com/Devoflex/module-chat

Homepage

Issues

Type:magento2-module

pkg:composer/chatixy/module-chat

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

v1.0.2 2026-08-19 20:15 UTC

This package is auto-updated.

Last update: 2026-08-19 20:15:22 UTC


README

Adds the Chatixy AI support agent to every front-end page of a Magento 2 / Adobe Commerce storefront. Install the module, paste your widget key in the admin, done. No theme edit, no Footer Misc HTML snippet to keep in sync, no layout override of your own.

Requirements

Magento magento/framework >= 103.0.0 (Magento 2.4 and later)
PHP 7.4+
Module name Chatixy_Chat (PSR-4 Chatixy\Chat\)

Install

composer require chatixy/module-chat
bin/magento module:enable Chatixy_Chat
bin/magento setup:upgrade
bin/magento cache:flush

Then open the admin and go to Stores -> Configuration -> Chatixy -> AI Support Agent -> General. Set Show support agent to Yes, paste the Widget key from your Chatixy dashboard, and save.

The key field accepts any of the three shapes the dashboard hands out:

  • the bare 64-character key,
  • <key>.js,
  • the whole <script src="https://chatixy.com/source/<key>.js" async></script> snippet.

The key is extracted from whatever you paste - the first 64-character hex run wins. Leave it empty and the module renders nothing at all.

Both settings are store-view scoped (chatixy/general/enabled and chatixy/general/widget_key), so a multi-store instance can run a different support agent - or none at all - per website or store view. Access to the section is gated by the Chatixy_Chat::config ACL resource, so it can be granted to an admin role on its own.

The tag ends up inside cached page HTML, so run bin/magento cache:flush after changing the key or the toggle.

No Chatixy account yet? Start at https://chatixy.com/register.

What it does

On every front-end page it renders one tag into the before.body.end container:

<script src="https://chatixy.com/source/<key>.js?platform=magento" async
        data-chatixy-source="magento"></script>

That is the whole payload. The URL is passed through escapeUrl() on the way out, and all of the logic (config read, key sanitisation, host pinning) lives in a ViewModel, so the template only ever prints a URL that has already been vetted.

before.body.end is used rather than a head block on purpose: the loader is position: fixed, so it does not matter where the tag sits, and body-end keeps it out of the critical render path.

What it deliberately does not touch

  • No database. There is no db_schema.xml, no setup script and no schema or data patch - the two settings live in core_config_data like any other configuration.
  • No di.xml, no plugins, no observers, no cron. The module adds one layout block and one ViewModel and preferences nothing.
  • Nothing in adminhtml beyond the config section itself, so the support agent never renders inside the admin.
  • Nothing at all when it is not configured. If the toggle is off, or the stored value contains no valid 64-character hex key, the ViewModel returns an empty string and the template outputs no markup.

Security: the origin is pinned

The widget key is public; the host is not configurable. The old Chatixy host (advanced) admin field was removed on purpose, because a stored host would build a first-party <script src> on every page of the storefront - i.e. store-wide stored XSS if it could ever be influenced, and a CSRF on the config form would be the way to influence it.

Chatixy\Chat\Model\WidgetKey::sanitizeHost() accepts only an https origin whose host is chatixy.com or a subdomain of it, and returns the canonical https://chatixy.com for anything else. The pattern is anchored at both ends and only ever grows the host to the left of a literal dot, so evilchatixy.com, chatixy.com.evil.example, chatixy.com@evil.example and http://chatixy.com are all rejected. A chatixy/general/host row left behind by an older version of the module is still read - and pinned like everything else - rather than left unread and unchecked.

There is one escape hatch, for developers working against a local Chatixy instance: the CHATIXY_ALLOW_INSECURE_HOST environment variable. It is a process-level switch (the shell that starts php-fpm, your Docker env), so nothing an HTTP request can reach can turn it on. Never set it on a production store.

Support

OSL-3.0 licensed, matching the license field in composer.json. See LICENSE.