chatixy / module-chat
Chatixy AI Support Agent - add the Chatixy AI support agent to your Magento storefront, no code.
Requires
- php: >=7.4
- magento/framework: >=103.0.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
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 incore_config_datalike 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
adminhtmlbeyond 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
- Docs and account: https://chatixy.com
- Help: https://chatixy.com/support
- Email: support@chatixy.com
OSL-3.0 licensed, matching the license field in
composer.json. See LICENSE.