Reputation: 131
I am trying to load an external script which embedds the "Buy Me A Coffee" widget onto a site. I am unable to get the script to execute unless I place the script in the _app.js
file. But by adding the script to the _app.js
file the widget is loaded on every page. I only want it loaded on a single page so I tried added the script to the head of the page I would like it loaded on:
<Head>
// Some content
<Script data-name="BMC-Widget" data-cfasync="false" src="https://cdnjs.buymeacoffee.com/1.0.0/widget.prod.min.js" data-id="some-id" data-description="Support me on Buy me a coffee!" data-message="" data-color="#5F7FFF" data-position="Right" data-x_margin="18" data-y_margin="18"/>
</Head>
that did not work and the docs say to add Script
tags outside of the Head
tags so I moved the script outside of the head tag like so:
<Head>
// Some content
</Head>
<Script data-name="BMC-Widget" data-cfasync="false" src="https://cdnjs.buymeacoffee.com/1.0.0/widget.prod.min.js" data-id="some-id" data-description="Support me on Buy me a coffee!" data-message="" data-color="#5F7FFF" data-position="Right" data-x_margin="18" data-y_margin="18"/>
But that still did not work. The widget is just not loading on the site unless I put the script into the _app.js
file.
I've read the documentation on the Script
and Head
tags for next.js but that is not helping out with this. I could definitely use some help with getting this to work.
Upvotes: 3
Views: 2402
Reputation: 11
Here is a simple Buy Me A Coffee Widget as a component. Edit the username, color and position.
'use client';
import { useEffect } from 'react';
export function BuyMeACoffee() {
useEffect(() => {
const script = document.createElement('script');
script.setAttribute('data-name', 'BMC-Widget');
script.src = 'https://cdnjs.buymeacoffee.com/1.0.0/widget.prod.min.js';
script.setAttribute('data-id', 'thaletto');
script.setAttribute('data-description', 'Support me on Buy me a coffee!');
script.setAttribute('data-message', '');
script.setAttribute('data-color', '#8FDCC2');
script.setAttribute('data-position', 'Right');
script.setAttribute('data-x_margin', '18');
script.setAttribute('data-y_margin', '18');
script.async = true;
script.onload = function () {
const event = new CustomEvent('DOMContentLoaded', {
bubbles: true,
cancelable: true,
});
window.dispatchEvent(event);
};
document.head.appendChild(script);
return () => {
document.head.removeChild(script);
const widget = document.getElementById('bmc-wbtn');
if (widget) {
document.body.removeChild(widget);
}
};
}, []);
return null;
}
Upvotes: 1
Reputation: 1
The buymeacoffee script loads the widget when the window is DOMContentLoaded event is fired (as seen in this answer). So you can use @dpacman's answer along with a content strategy of 'beforeInteractive'
Upvotes: 0
Reputation: 3899
I had the same problem, this is how you add a third-party script in next.js.
<Head>
// Some content
</Head>
<Script
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `
(function (d, s, id) {
var js,
el = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement(s);
js.async = true;
js.src = "https://cdnjs.buymeacoffee.com/1.0.0/widget.prod.min.js";
js.id = id;
js.charset = "UTF-8";
el.parentNode.insertBefore(js, el);
})(document, "script", "buymeacoffee-js");
`,
}}
/>
Upvotes: 2