Turbolinks与Drift Chat兼容问题:首次加载后组件无法重载
Fixing Drift Chat Reload Issues with Turbolinks
It looks like your problem stems from how Turbolinks handles page navigation combined with Drift's initialization lifecycle. Here's what's going wrong and how to fix it:
Root Causes
- Turbolinks replaces the page body without a full reload, so Drift's initial snippet only runs once on the first page load.
- The
readyevent you're listening to in yourturbolinks:loadhandler only fires once (on the initial page load), so after Turbolinks navigates, that callback never executes to show the widget. - Without resetting Drift between page loads, the widget can end up in a stale state where API calls like
widget.show()don't work as expected.
Solution Code
Replace your existing script with this revised version that properly handles Turbolinks navigation:
<head> <script> "use strict"; !function() { var t = window.driftt = window.drift = window.driftt || []; if (!t.init) { if (t.invoked) return void (window.console && console.error && console.error("Drift snippet included twice.")); t.invoked = !0, t.methods = [ "identify", "config", "track", "reset", "debug", "show", "ping", "page", "hide", "off", "on" ], t.factory = function(e) { return function() { var n = Array.prototype.slice.call(arguments); return n.unshift(e), t.push(n), t; }; }, t.methods.forEach(function(e) { t[e] = t.factory(e); }), t.load = function(t) { var e = 3e5, n = Math.ceil(new Date() / e) * e, o = document.createElement("script"); o.type = "text/javascript", o.async = !0, o.crossorigin = "anonymous", o.src = "https://js.driftt.com/include/" + n + "/" + t + ".js"; var i = document.getElementsByTagName("script")[0]; i.parentNode.insertBefore(o, i); }; } }(); drift.SNIPPET_VERSION = '0.3.1'; drift.load('XXXXXXXXXXX'); // Reset Drift before Turbolinks renders new content $(document).on("turbolinks:before-render", function() { if (window.drift && typeof drift.reset === 'function') { drift.reset(); } }); // Reinitialize Drift on Turbolinks page load $(document).on("turbolinks:load", function() { // Clear existing ready listeners to avoid duplicate callbacks drift.off('ready'); drift.on('ready', function(api) { console.log("Drift ready (Turbolinks load)"); // Re-apply Drift configuration drift.config({ enableWelcomeMessage: false, locale: "<%=I18n.locale%>" }); // Set user attributes if user is authenticated <% if current_user %> api.setUserAttributes({ user_id: <%=current_user.id%>, email: "<%=current_user.email%>" }); <% end %> // Show the chat widget api.widget.show(); // Reattach click handler for chat open button (DOM was replaced by Turbolinks) $('.drift-open-chat').off('click').on('click', function(e) { api.widget.show(); api.sidebar.open(); e.preventDefault(); }); }); }); </script> </head>
Key Changes Explained
turbolinks:before-renderHandler:- Calls
drift.reset()to clear user state and reset the widget before Turbolinks loads new content. This ensures we start fresh with each page navigation.
- Calls
turbolinks:loadHandler:- Uses
drift.off('ready')to remove any existingreadylisteners, preventing duplicate callbacks from firing. - Listens for the
readyevent again to get a fresh API reference after reset. - Reapplies your Drift configuration (since reset clears previous settings).
- Re-sets user attributes for authenticated users (critical because reset removes this data).
- Calls
api.widget.show()with the fresh API reference to ensure the widget displays correctly. - Reattaches the click handler for
.drift-open-chat(Turbolinks replaces the DOM, so old listeners are gone).
- Uses
This should resolve your issue where the Drift widget doesn't reload after the first page load with Turbolinks.
内容的提问来源于stack exchange,提问作者sparkle
相关产品推荐
相关产品推荐

