A support chat that survives a page reload. Without an iframe and without third-party cookies.

← All articles

A support chat that survives a page reload. Without an iframe and without third-party cookies.

Why embedded chats lose their session, and how wg_chat keeps it in the host page's own storage. Honest trade-offs included.

Most embeddable chat widgets live in an iframe on another domain. That is fine until the visitor reloads the page. Now the chat has to remember which conversation it was in. The places a third-party widget can keep that are getting smaller.

Safari blocks third-party cookies by default. Firefox keeps them in a separate jar for every site. Storage inside a cross-site iframe is partitioned in all major browsers. Whether a given iframe chat keeps its session depends on where its vendor stores it. Some do it well. Many rely on a cookie on their own domain, and that is the part that breaks.

We built wg_chat so the question does not come up. It does not run in an iframe. It renders into the page that embeds it. So whatever it writes to localStorage is first-party storage of that site. It lives as long as the site's own storage does.

What the browser keeps

Only a conversation id and an HMAC over it (SHA-256). That is not a session key. It lets the browser find its own conversation again on that one site. It grants nothing else and is useless anywhere else.

The transcript stays on the server, encrypted with AES-256. If a visitor clears their storage, nothing is lost. They start a new conversation and the operator still has the old one.

How new messages arrive

Plain HTTP polling with fetch. Every 4 seconds by default, and you can set it down to 1.5 seconds. There is no WebSocket and no extra service to run. That is a real trade-off. It runs on any PHP host, but it is not instant, and every open chat costs one small request every few seconds.

What protects it

  • The operator logs in with a key that is stored with password_hash. After 8 wrong attempts in 15 minutes an IP has to wait.
  • Rate limits allow 6 new conversations and 20 messages per 5 minutes.
  • A honeypot field catches simple bots.
  • It is plain JavaScript. No jQuery, no framework, nothing extra pulled into your page.

It needs PHP 7.0 or newer with openssl and one writable directory. It uses SQLite when it is available and an encrypted file when it is not.

Putting it on a page

With your personal wgclient.php, your own server renders the chat before the page goes out. It is part of the initial HTML, and the transcript is stored on that same server.

<?php include "wgclient.php";
$wg->get("wg_chat", "WidgetStormSystem", '{"title":"Support","wglang":"en"}', ""); ?>

The empty last argument means CSS, HTML and JS come together. You can also ask for each part on its own and place it yourself.

Host CSS reaches the widget, because it is part of your page. If your design system says buttons are round, the chat's buttons can be round too.

Try it first

There is a live demo on the widgets page. It runs on the page itself and keeps nothing: widget-storm.de/en/widgets#premium

wg_chat costs €4.99 once. No subscription. Total price. No VAT is charged under the small-business rule of section 19 of the German VAT Act.

If something here does not match what you see, tell us. We would rather fix the article than defend it.

Try Widget Storm

The widgets run as live demos right on the page. Public widgets can be embedded freely into their own projects by any registered user.

Browse the widgets Support chat without an iframe: €4.99 one-time

Total price · no VAT (§ 19 UStG)