Nuxt.js集成Clutch Widget后路由切换返回组件消失问题求助
Hey there, I’ve dealt with this exact headache with third-party widgets in Nuxt before—let’s get your Clutch Widget staying put when navigating routes!
The Root Cause
Nuxt works as a single-page application (SPA), so when you switch routes, the page doesn’t fully reload. Your current setup loads the Clutch script once (via the head() method) and runs the callback on first load, but when you navigate back to the page:
- The script is already loaded, so the callback doesn’t fire again
- The Clutch Widget’s auto-initialization only runs when the script first loads—your widget DOM element exists, but the widget doesn’t re-render it
Step-by-Step Solution
1. Adjust Script Loading
First, let’s separate script loading from initialization. Update your head() method to just load the script (no callback needed, since we’ll handle initialization manually):
head () { return { script: [ { hid: 'clutch', type: 'text/javascript', src: 'https://widget.clutch.co/static/js/widget.js', defer: true } ] } },
The hid attribute ensures Nuxt only loads the script once across routes, which is efficient.
2. Add a Widget Initialization Method
Create a reusable method to trigger the Clutch Widget initialization. This checks if the script is already loaded, then re-renders the widget:
methods: { initClutchWidget() { // Wait for the Clutch Widget global to exist if (window.ClutchWidget) { // Re-initialize the widget to render the DOM element window.ClutchWidget.init(); } else { // Fallback: if the script hasn't loaded yet, load it and initialize on finish const script = document.createElement('script'); script.src = 'https://widget.clutch.co/static/js/widget.js'; script.defer = true; script.onload = () => window.ClutchWidget?.init(); document.head.appendChild(script); } } },
3. Trigger Initialization on Page Entry
We need to run this method every time the component is rendered (not just on first page load). Use a combination of mounted and a route watcher, or a navigation guard:
Option A: Mounted + Route Watcher
mounted() { // Initialize when the component first mounts this.initClutchWidget(); }, watch: { '$route' (to) { // Re-initialize when navigating back to this specific page if (to.path === '/your-target-page-path') { this.initClutchWidget(); } } }
Option B: Navigation Guard (Cleaner for Specific Pages)
beforeRouteEnter(to, from, next) { // Run initialization right before the route enters the component next(vm => vm.initClutchWidget()); }
Bonus: Use a Nuxt Plugin (For Reusable Widgets)
If you need the Clutch Widget across multiple pages, wrap it in a client-side plugin to load the script once globally:
- Create
plugins/clutch-widget.js:
export default ({ app }) => { if (process.client) { const loadClutchScript = () => { const script = document.createElement('script'); script.src = 'https://widget.clutch.co/static/js/widget.js'; script.defer = true; script.onload = () => { window.ClutchWidget = window.ClutchWidget || {}; }; document.head.appendChild(script); }; loadClutchScript(); } };
- Register the plugin in
nuxt.config.js:
plugins: [ { src: '~/plugins/clutch-widget.js', mode: 'client' } ]
Then you can use the same initClutchWidget method in any component without reloading the script.
Why Your Previous Setup Failed
The callback in the head() script only runs once—when the script is first downloaded. After that, navigating back doesn’t trigger the script to reload, so the callback never fires again, and the widget doesn’t re-initialize. By manually calling window.ClutchWidget.init() on page entry, we force the widget to render its DOM element every time the component is active.
内容的提问来源于stack exchange,提问作者Md. Abdullah Al Mamun

