frames-react
frames-react copied to clipboard
Enhancement: Improve 'frames-react' to Handle Script Loading from CDN Automatically
I am having issues when I want to use the frames I always get this error:
Frames was used before the script (from the CDN) was loaded completely
so it would be better if frames-react
also handles loading the script from the CDN
and then initialize the frames instead of me having to wait for it to load, and running into unexpected issues
I tried several ways to add the script but each time I run into unexpected error:
used nextjs/head
to add the script:
<Head>
<script src="https://cdn.checkout.com/js/framesv2.min.js" async />
</Head>
but if I leave the page and visit it again I get:
Frames was used before the script (from the CDN) was loaded completely
I even tried to use a custom solution to load the script manually on page mount and wait for it to load:
import { useEffect } from "react";
const useExternalScripts = (
src: string,
attributes: Record<string, string> = {},
onload: (() => void) | null = null,
appendToHead: boolean = false
) => {
useEffect(() => {
const tempScript = document.createElement("script");
tempScript.setAttribute("src", src);
Object.keys(attributes).forEach((att) => {
tempScript.setAttribute(att, attributes[att]);
});
tempScript.onload = () => {
if (onload) {
onload();
}
};
if (appendToHead) {
document.head.appendChild(tempScript);
} else {
document.body.appendChild(tempScript);
}
// Clean up the script when the component unmounts
return () => {
if (tempScript) {
tempScript.remove();
}
};
}, [src, attributes, onload, appendToHead]);
};
export default useExternalScripts;
usage:
import { useState } from "react";
import { CardFrame } from "frames-react";
import useExternalScripts from "@/hooks/useExternalScripts";
const CardCheckout = () => {
const [loaded, setLoaded] = useState<boolean>(false);
useExternalScripts(
"https://cdn.checkout.com/js/framesv2.min.js",
{},
() => {
setLoaded(true);
},
true
);
if (!loaded) {
return <div>Loading...</div>;
}
return (
<div className="overflow-hidden">
<CardFrame />
</div>
);
};
export default CardCheckout;
but in the custom solution when I submit the form I get
Uncaught (in promise) Card form invalid
I even logged the event I get from events and the form is valid:
cardValidationChanged
:
{
isValid: true,
isElementValid: {
cardNumber: true,
expiryDate: true,
cvv: true,
schemeChoice: true
}
};
frameValidationChanged
:
{
element: "cvv",
isValid: true,
isEmpty: false,
isFormValid: true,
isFormEmpty: false
};
so the best thing to resolve all these issues is to auto-load the script