Enter a symptom to get the behavior, official positioning and L2 root cause (why the JS injection fails / gets blocked). Below: a full symptom table, an injection diagram, five integration methods compared with 2026 estimates, and FAQ.

Whatever "chat didn't appear" you have, narrow it to four buckets first - this alone saves most of the detours. The flowchart makes the decision clear: check whether the script even loaded (meiqia.js in F12), then whether it's config, framework or a display-layer issue. For the basics see the Meiqia website integration guide.
One sentence is enough: the Meiqia web widget isn't a static component in your page - it's a meiqia.js loaded asynchronously from Meiqia's off-domain origin that dynamically injects a chat container (DOM / iframe) and opens a cross-origin long-lived connection. For injection to succeed it needs "the script loaded (right placement, not ad-blocked), the container not covered by site CSS / other plugins, entId & domain matching, and re-mount after an SPA route change". The diagram below draws this chain and four common block points - exactly why the same code works on one site / framework but not another.
If placement, meiqia.js 200 and entId are all confirmed but it still won't show, it's basically "ad blocker" or "framework / stacking". The panel below is ordered by importance: green is usually fine, the red ones (ad blocker, SPA / third-party plugin stacking) are the frequent traps. Checking item by item localizes it fast.

The table below lists the common not-showing / error symptoms at once, each with its official positioning and L2 root cause. The search box above is driven by this table's data - search the keyword you hit.
| Symptom | Bucket | L1 behavior / official positioning | L2 root cause |
|---|---|---|---|
| Chat window / bubble not showing at all | Load failure | The Meiqia web widget loads a floating chat window from a single pasted JS snippet; confirm the code is correctly embedded and the integration site is configured in the console. | The widget is meiqia.js injected into the DOM after an async load, so "nothing at all" usually means "the script never loaded" - wrong placement, blocked by an ad blocker / cache, or unmatched domain / entId, so the injection step never ran. |
| Script loaded but chat button missing | Display issues | The widget code auto-adapts to the site and shows a chat button; if display is off, check whether it's hidden by styles or initialization was interrupted. | If the script loads but the button is missing, it's usually a "display layer" issue: site-wide CSS overrides the button position / sets display:none, the z-index loses, or another fixed element covers it; another JS error on the page can also abort initialization. |
| meiqia.js blocked by an ad-blocker extension | Load failure | The Meiqia chat script comes from a third-party domain; if a blocking extension is installed it may treat it as an ad / tracker and prevent loading - turn off blocking or whitelist. | ERR_BLOCKED_BY_CLIENT means a browser extension (AdBlock / uBlock / AdGuard) blocked the request by its filter lists. The Meiqia script is "third-party off-domain + realtime comms", which such rules often misread as an ad / tracker, causing a "console fine, user side missing" false failure. |
| meiqia.js 404 / bad status / mixed content | Load failure | After deploying, search meiqia.js in the Network panel; a 200 status means the script is correctly placed and loaded. | Common non-200 causes: code held by page / CDN cache (no refresh after publishing), loaded on an HTTP page / incomplete cert chain triggering mixed-content blocking, or broken / partially copied code. With this step failed, injection and the connection never happen. |
| Code in the wrong place (head blocking / no effect) | Load failure | Meiqia recommends pasting the code at the bottom of the page, before the </body> tag; the widget runs after the page's main content loads. | The widget must inject its container after the DOM is ready. In <head> it blocks rendering (a blank screen first on a weak network) or runs before the DOM is ready and fails to inject; inside some async / module scope the load order can also go wrong. |
| Chat window / button styling broken | Display issues | The widget injects its own styles and auto-adapts to the site; conflicts with site-wide styles can cause visual glitches. | The Meiqia script injects CSS at runtime; if site-wide styles (universal selectors / high-priority rules / resets) override its classes first, the button position, stacking and fonts break - a side effect of "dynamic injection + sharing one document style space". |
| Button off-screen / covered | Display issues | The widget button appears as a fixed-position float; if covered by other fixed elements, adjust the stacking or position. | Other position:fixed elements on the site (back-to-top, floating ads, a custom support bar) with a higher z-index cover the Meiqia button, or the theme miscomputes its coords, so the button is "off-screen / covered". |
| Third-party plugin / analytics DOM conflict | Display issues | Other scripts on the page that modify the DOM or intercept requests can affect the widget's normal loading and display. | Heatmap / analytics / conversion scripts rewrite the DOM, inject overlays or intercept requests; since they and Meiqia both inject into the same document, stacking / events interfere and the Meiqia container gets covered or its init interrupted. |
| Widget disappears after an SPA route change | Framework integration | For single-page apps (SPA), use the framework's route hooks to load / init the Meiqia widget so it fits front-end routing. | An SPA swaps views via front-end routing, destroying / rebuilding the DOM, but meiqia.js injects once on first load by default and won't auto-rebuild on a route change, so "change page, chat's gone". |
| Manual init needed (manualInit / init) | Framework integration | Add _MEIQIA('manualInit') after the Meiqia embed code to stop auto-init after download; call _MEIQIA('init') to initialize manually when needed. | By default Meiqia auto-inits right after download; when you need the container ready / customer info passed / the route settled first, that timing is "too early" - switch to manual init to control the sequence. |
| entId mismatch / agents get no chats | Config / authorization | The number after entId in the code is your company's unique id; a mismatch with the workbench means agents can't serve the chat - find the company ID under Settings - Team - ID lookup. | entId binds the snippet to a specific company account. With someone else's / another environment's code, or mixed-up accounts, the front end loads the window but messages go to "another company", so this workbench gets none - the classic "shows fine but receives nothing". |
| Site domain not authorized in the console | Config / authorization | The Meiqia console can "Add integration site", each with its own config; a new site must be configured in the console before it integrates properly. | Meiqia manages multiple sites as "integration sites"; the domain must be registered / authorized in the console to be recognized. A new production domain not added there may not be accepted or mapped to the right config. |
| Multi-site / sub-channel (probe) cross-wiring | Config / authorization | Meiqia supports deploying different widgets and chat links per site (sub-channels / probe); beyond the default site you can add more, each with its own config. | Different business lines need different agent groups / auto-messages, but if every site shares the one default snippet, sources can't be told apart and configs cross-wire. Sub-channels (probe) are designed for "one company, many entries, routed". |
| Mobile web chat not showing / needs separate deploy | Mobile / SDK | The widget code auto-adapts to the site; mobile / PC use the same snippet but it must be deployed separately. | Many teams have separate PC and mobile pages / templates and only pasted the code in the PC template. The snippet is the same and self-adapts, but the "paste" step must happen in the mobile template too; miss it and mobile has none. |
| Native app SDK integration / AppKey | Mobile / SDK | In-app integration needs an AppKey from the Meiqia workbench (Settings - Integration - SDK, "Add APP config"), with developers integrating the iOS / Android SDK per the official docs and demo. | An app uses the native SDK, not web JS: first "Add APP config" for an AppKey, then integrate the SDK per platform for the chat UI, unread counts, push, etc. - a completely different path from the web widget. |
| SDK message push not arriving | Mobile / SDK | Meiqia SDK push has two modes: with "no push", agent messages reach only inside the app (open the app to receive); with a "custom push server", users get push to the phone even after leaving the app. | Missing "offline push" usually means the push mode is "no push", or there's no custom push server / per-platform push certs. The path is "Meiqia -> app server -> user's phone"; a missing link means in-app-only receipt. |
| Hide the default button / custom entry | API calls | Call _MEIQIA('withoutBtn') to not show Meiqia's built-in chat button; after init succeeds, call _MEIQIA('showPanel') to open the chat. | By default the built-in floating button renders; to use your own entry you must declare "no built-in button" before / during init and bind "open chat" to your element - an API-timing matter, not a "broken button". |
| Passing / syncing customer info has no effect | API calls | The Meiqia web widget offers "pass customer info", "sync customer identity" and "add customer custom event info" APIs to bring visitor data into the chat. | These APIs must be called within the correct init timing: set after init succeeds (or with manualInit + init timing). Too early / too late, or wrong field formats, and it's "set but no effect". |
The following are 2026 estimates synthesized from Meiqia's official help (Access Channels / JavaScript web widget API) and public integration troubleshooting (not vendor commitments, not first-hand measurement; for reference, shifts by version and browser policy):
| Dimension | Estimate / comparison |
|---|---|
| Not-showing cause split (community / tickets . est.) | placement / not loaded ~35% > ad blocker / browser extension ~25% > config / auth (entId / domain) ~20% > framework (SPA) ~12% > style / third-party plugin conflict ~8% |
| What integration really is | the web widget = third-party off-domain async JS injecting the DOM + a cross-origin long-lived connection (not an embedded static component); hence affected by placement, ad-block rules, page CSS stacking, SPA lifecycle |
| Per-platform integration (est.) | PC / mobile web = JS widget (same code, deployed separately); app = native SDK (AppKey); WeChat / Douyin / RED = channel-authorized integration |
| Ad-blocker impact (est.) | about 30-40% of PC users run an ad-blocker extension -> the third-party chat script is blocked by ad rules (ERR_BLOCKED_BY_CLIENT), a leading cause of "console fine, user side missing" |
| JS widget time to live (official) | paste the dedicated JS at the page bottom and it goes live in about 3-5 minutes; entId is the company's unique id, and a mismatch with the workbench means agents get no chats |
Estimate basis: source baseline + time extrapolation (meiqia.com/help Access Channels / JavaScript web widget, meiqia.im website-integration guide, public integration troubleshooting, 2026); shifts with version and browser blocking policy. Rely on Meiqia's latest official info.


Which integration method? The comparison below synthesizes Meiqia's official docs for a quick cross-reference (code volume, feature completeness, best fit, time to live). Most sites pick the "web JS widget".
| Integration method | Code / difficulty | Feature completeness | Best for | Time to live |
|---|---|---|---|---|
| Web JS widget | one JS snippet . low | fullest (float / popup / auto-greet / visitor trail) | PC + mobile sites (officially recommended) | ~3-5 min |
| Chat link | no code . lowest | basic chat | no-tech / drop in a quick chat link | instant |
| API / WebIM SDK | needs dev . high | deep customization (custom UI / system / order integration) | teams with dev capacity for deep fusion | depends on dev |
| Native app SDK | integrate SDK . high | in-app chat + message push | iOS / Android apps | depends on dev |
| CMS quick setup | plugin / one-click . low | same as the JS widget | WordPress / Fkw / Shopify sites | minutes |
The same Meiqia integrates differently per channel / scenario. The map below shows common channels: green = paste and go, amber = needs setup (separate deploy / init / whitelist), red = switch method by default (ad blocker / entId / app uses SDK).
The Meiqia web widget loads a floating chat window from a single pasted JS snippet; confirm the code is correctly embedded and the integration site is configured in the console. The widget is meiqia.js injected into the DOM after an async load, so "nothing at all" usually means "the script never loaded" - wrong placement, blocked by an ad blocker / cache, or unmatched domain / entId, so the injection step never ran. F12 -> Network, search meiqia.js: no request -> code not in effect (check placement / clear cache); a request but non-200 -> blocked or a path issue; all fine but still hidden -> check entId / domain authorization and the buckets below.
The widget code auto-adapts to the site and shows a chat button; if display is off, check whether it's hidden by styles or initialization was interrupted. If the script loads but the button is missing, it's usually a "display layer" issue: site-wide CSS overrides the button position / sets display:none, the z-index loses, or another fixed element covers it; another JS error on the page can also abort initialization. F12 -> Elements, find the Meiqia container - is it present, hidden, or off-screen; temporarily disable custom CSS / other scripts to retest; check the console for an error that aborted execution.
The Meiqia chat script comes from a third-party domain; if a blocking extension is installed it may treat it as an ad / tracker and prevent loading - turn off blocking or whitelist. ERR_BLOCKED_BY_CLIENT means a browser extension (AdBlock / uBlock / AdGuard) blocked the request by its filter lists. The Meiqia script is "third-party off-domain + realtime comms", which such rules often misread as an ad / tracker, causing a "console fine, user side missing" false failure. Retest in incognito or with the ad blocker off - if it shows, blocking was the cause; ask users to whitelist the site; the front end can delay / conditionally load the chat script to dodge some auto-rules.
After deploying, search meiqia.js in the Network panel; a 200 status means the script is correctly placed and loaded. Common non-200 causes: code held by page / CDN cache (no refresh after publishing), loaded on an HTTP page / incomplete cert chain triggering mixed-content blocking, or broken / partially copied code. With this step failed, injection and the connection never happen. Clear CDN / browser cache (or use incognito) after publishing; ensure full HTTPS with a complete cert chain and no mixed content; verify the copied code is complete and unescaped.
Meiqia recommends pasting the code at the bottom of the page, before the </body> tag; the widget runs after the page's main content loads. The widget must inject its container after the DOM is ready. In <head> it blocks rendering (a blank screen first on a weak network) or runs before the DOM is ready and fails to inject; inside some async / module scope the load order can also go wrong. Put the Meiqia JS in the common footer of every page, before </body>; for SPAs see the "SPA route" entry and use manualInit; make sure a bundler doesn't tree-shake it away.
The widget injects its own styles and auto-adapts to the site; conflicts with site-wide styles can cause visual glitches. The Meiqia script injects CSS at runtime; if site-wide styles (universal selectors / high-priority rules / resets) override its classes first, the button position, stacking and fonts break - a side effect of "dynamic injection + sharing one document style space". F12 to see which site rule overrides the Meiqia container; scope site-wide styles more narrowly / reduce their impact on generic classes; if needed ask Meiqia to adjust the container layering.
The widget button appears as a fixed-position float; if covered by other fixed elements, adjust the stacking or position. Other position:fixed elements on the site (back-to-top, floating ads, a custom support bar) with a higher z-index cover the Meiqia button, or the theme miscomputes its coords, so the button is "off-screen / covered". Select the Meiqia container in F12 to see its real coords / z-index; raise it or lower the covering element's z-index; avoid stacking multiple fixed floats in one corner.
Other scripts on the page that modify the DOM or intercept requests can affect the widget's normal loading and display. Heatmap / analytics / conversion scripts rewrite the DOM, inject overlays or intercept requests; since they and Meiqia both inject into the same document, stacking / events interfere and the Meiqia container gets covered or its init interrupted. Disable suspect plugins one by one to locate the conflict; adjust load order / container layering; have heatmaps etc. avoid the Meiqia container area.
For single-page apps (SPA), use the framework's route hooks to load / init the Meiqia widget so it fits front-end routing. An SPA swaps views via front-end routing, destroying / rebuilding the DOM, but meiqia.js injects once on first load by default and won't auto-rebuild on a route change, so "change page, chat's gone". Use _MEIQIA('manualInit') to stop auto-init, and call _MEIQIA('init') in a route hook (React useEffect / Vue mounted / router afterEach) to re-mount on demand; avoid initializing multiple instances.
Add _MEIQIA('manualInit') after the Meiqia embed code to stop auto-init after download; call _MEIQIA('init') to initialize manually when needed. By default Meiqia auto-inits right after download; when you need the container ready / customer info passed / the route settled first, that timing is "too early" - switch to manual init to control the sequence. Add _MEIQIA('manualInit') after the embed code; call _MEIQIA('init') once conditions are ready (DOM / login state / route); call info APIs in order within the init timing per the docs.
More integration setup: Meiqia website integration, APP SDK integration; getting started: Meiqia guide. A full searchable version (incl. this tool) is also at Meiqia integration troubleshooting (GitHub Pages).