checkout / frames-react

React wrapper of Checkout.com Frames.

Home Page:https://docs.checkout.com/integrate/frames

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Enhancement: Improve 'frames-react' to Handle Script Loading from CDN Automatically

yaman3bd opened this issue · comments

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