To add live chat to Symfony you need one small Twig partial, one line in your base template and a way to keep the script address out of your code. The partial holds the Talkmio snippet, the base template includes it just before the closing body tag, and a check on the environment keeps the widget out of your local and test runs. That is the whole job, and for an application that already has a base template it takes about fifteen minutes.
Talkmio is an AI live chat for websites. Its assistant, Mio, answers visitors in their own language from your website, FAQ and uploaded documents, and hands the conversation to your team when it cannot answer. A Symfony site is a good fit, because the public pages Mio needs are normally rendered by Twig templates and are easy to crawl. This guide shows the clean way to add live chat to Symfony, and the problems to check afterwards.
What You Need Before You Start
Create a free account at app.talkmio.com, confirm your e-mail and add your website under Websites. You receive a site key and an install snippet. The examples below use the placeholder SCRIPT_ADDRESS_FROM_YOUR_SNIPPET for the script address. Copy the real value from your own snippet, and do not edit anything else in it.
You also need to know where your public pages get their layout. In a standard Symfony application with Twig, that is templates/base.html.twig, which other templates extend. The Symfony templates documentation explains inheritance and includes. If your site has a separate layout for the public pages and the admin area, use the public one only. Visitors should see the chat, and your back office should not.
Ways to Add Live Chat to Symfony
The snippet can reach the page in several ways. The table compares them so you can choose before you write code.
| Method | Effort | Keeps the script address out of code | Best for |
|---|---|---|---|
| Paste the snippet into base.html.twig | Lowest | No | Small sites and quick tests |
| Twig partial included from the base template | Low | No | Most applications |
| Partial plus an environment variable exposed as a Twig global | Medium | Yes | Teams with several environments |
| Loading through Google Tag Manager | Medium | Yes | Teams that already manage scripts in a container |
The third row is the one we recommend when you can spare ten extra minutes. It keeps the value in configuration, so staging and production can differ, and it makes the widget easy to switch off without a deployment of new code.
Step 1: Create the Partial
Create the file templates/_partials/talkmio.html.twig and paste the snippet into it. The script is loaded asynchronously, so it does not block rendering.
{# templates/_partials/talkmio.html.twig #}
<script async src="SCRIPT_ADDRESS_FROM_YOUR_SNIPPET"></script>
Now include it in the base template, just above the closing body tag, and wrap it in a block so that single pages can switch it off later.
{# templates/base.html.twig #}
{% block talkmio %}
{% include '_partials/talkmio.html.twig' %}
{% endblock %}
</body>
</html>
Reload a page and the chat bubble appears in the corner. If your base template already has a javascripts block at the end of the body, you can put the include inside it instead, but a dedicated block is easier to find in a year.
Step 2: Show the Widget Only in Production
You do not want test chats from your laptop or your continuous integration run to land in the Inbox of your team. Twig exposes the application through the app variable, and app.environment gives the current environment name. The reference page for Twig in Symfony lists the other helpers.
{% block talkmio %}
{% if app.environment == 'prod' %}
{% include '_partials/talkmio.html.twig' %}
{% endif %}
{% endblock %}
If you run a staging server in the prod environment with a different host, add a second condition or use the configuration approach in the next step, so that staging does not show the widget.
Step 3: Keep the Script Address in an Environment Variable
Hard-coded addresses are the usual source of the mistake where a staging site talks to a production account. Put the value in an environment variable, read it in configuration and expose it to templates as a Twig global.
# .env
TALKMIO_SCRIPT_SRC=
# .env.local on the production server, or a real environment variable
TALKMIO_SCRIPT_SRC=SCRIPT_ADDRESS_FROM_YOUR_SNIPPET
# config/packages/twig.yaml
twig:
globals:
talkmio_script_src: '%env(TALKMIO_SCRIPT_SRC)%'
{# templates/_partials/talkmio.html.twig #}
{% if talkmio_script_src %}
<script async src="{{ talkmio_script_src }}"></script>
{% endif %}
Now the empty default in .env means the widget does not render anywhere unless a value is set. You enable it on production by setting the variable there, and the environment check from step 2 becomes optional. Symfony’s page on environment variable processors explains the syntax, and how to keep secrets safe if you use a vault. The script address is not a secret, but the habit is good.
Remember to clear the cache after you change the configuration, and run the command as the web server user on your server, so that cache files keep the right ownership.
Step 4: Switch the Chat Off on Selected Pages
Some pages should not carry a bubble: a printable invoice, a checkout step you want to keep clean, or a kiosk view. Because the include sits in a block, a child template can empty it.
{# templates/invoice/print.html.twig #}
{% extends 'base.html.twig' %}
{% block talkmio %}{% endblock %}
Keep the list of exceptions short. A chat that is missing on half the site confuses visitors, and the pages where people hesitate, such as pricing and checkout, are often where help matters most. Our article on live chat and Google Tag Manager describes the alternative of managing the script in a container, which suits teams that change it often.
Turbo, Stimulus and Single-Page Navigation
If you use Symfony UX Turbo, links are followed without a full page load. Turbo Drive replaces the body on each visit, and scripts in the new body can run again. The effect on a chat widget depends on how the widget starts, so test it rather than assume. Click through five pages and count the chat bubbles. If you see more than one, or if the bubble flickers, move the include into the head so that it is added once, and test again.
The same caution applies to applications that mount a front-end framework inside a Twig page. The widget lives outside your framework, so it should survive route changes, but a full test on a phone is worth the five minutes.
Content Security Policy and Caching
If your application sends a Content Security Policy header, either from a bundle or from the web server, the policy must allow the script and the connections the widget makes. Copy the addresses from your snippet and add them to the matching directives. The MDN guide to CSP explains the directives. After a change, open the browser console on a production page and look for blocked requests.
Caching is simpler. The widget is added by the same markup for every visitor, so a full-page cache, a reverse proxy or a CDN can serve the same HTML to everyone. You do not need to purge anything when you change widget colours, position or texts in Talkmio, because those settings apply within five minutes under Websites.
Teach Mio From Your Symfony Site
Installing the snippet is half of the work. In Talkmio, open Mio AI, then Knowledge base, and add your deployed site. Mio reads every public page on the same domain and respects robots.txt. Pages behind a login are not public, so Mio will not see them. If your product documentation or price list lives in files, upload them: PDF, DOCX, TXT, MD, CSV and HTML are supported, up to 15 MB each.
Then write business instructions: what you sell, the tone to use and what Mio must never promise. Use Try Mio to test questions before you go live. After each release that changes prices or policies, use the re-read option so Mio picks up the change. Mio answers only from your content and never invents prices or policies. Our guide on adding live chat to Laravel covers the same ideas for another PHP framework, and the general instructions to add live chat to any website apply if your setup is unusual.
Common Problems When You Add Live Chat to Symfony
- No bubble appears. View the page source. If the script tag is missing, the environment check is false, the global is empty or the cache holds an old template. Clear the cache and reload.
- The bubble appears twice. Both the base template and a child block include the partial, or Turbo runs the script again. Search the rendered HTML for the script address.
- The widget appears in the admin area. The admin pages extend the same base template. Override the block in the admin base template.
- Blocked by the browser. A content security policy or an ad blocker rule hides it. Check the console.
- Staging shows production chats. The same script address is set in both environments. Use separate values or leave staging empty.
If you maintain several sites on different generators, the guide to adding live chat to a static site covers the generic steps, and the cookie guide on cookies and consent for chat widgets helps you decide how to treat the widget under your consent banner.
Test Before You Announce It
- Deploy to production and open a page in a private browser window. The bubble appears in the corner.
- View the source and confirm the script appears once.
- Run the application locally and confirm that the widget does not appear.
- Ask Mio two or three questions your customers often ask. Each answer should come from your own pages.
- Ask for a person. The conversation should appear in the Inbox with a needs-human badge, and your browser should notify you.
- Open a page where you emptied the block and confirm that the bubble is absent.
- Test on a phone, and navigate through several pages if you use Turbo.
Frequently Asked Questions
Do I need a Symfony bundle to add live chat?
No. The Talkmio snippet is a plain script tag, so you add it to a Twig template. There is no bundle to install and no PHP code to write. The WordPress plugin is only for WordPress sites. Any Symfony application that renders HTML through Twig can use the snippet in a partial.
Where should the snippet go in a Symfony application?
Put it in a partial such as templates/_partials/talkmio.html.twig, and include it from base.html.twig just before the closing body tag, inside its own block. A dedicated block lets child templates remove the widget on single pages. Use the public layout only, so that your admin area stays free of it.
How do I keep the chat out of dev and test environments?
Wrap the include in a check on app.environment, or expose the script address through an environment variable and leave it empty everywhere except production. The second approach is more robust, because staging servers that run in the prod environment can stay empty too, and you can switch the widget off without changing code.
Does it work with Symfony UX Turbo?
It usually does, but the behaviour depends on how the widget starts, so test it. Navigate through several pages and count the bubbles. If you see more than one, place the include in the head so that it is added once and check again on a phone.
Will Mio know about my Symfony content automatically?
After you add your deployed site to the knowledge base, Mio reads every public page on the same domain and respects robots.txt. Pages behind a login are not public and are not read. After you publish changes, use the re-read option, and upload any private documents as files.
Can I try it before I pay?
Yes. The Free plan includes one operator, one website, 50 AI answers a month, 50 tickets a month and 20 knowledge base pages, with no card. Paid plans add operators, websites, AI answers and the e-mail channel. Check the pricing page for current figures before you decide.
The Bottom Line
To add live chat to Symfony, create one Twig partial, include it in a block at the end of the base template, keep the script address in an environment variable and leave it empty outside production. Use the block to switch the widget off on the few pages that need it, and test Turbo navigation and your content security policy. Then teach Mio from your public pages. Start free with Talkmio, add your site and see how many of your visitors’ questions Mio can answer on its own.
