skip to Main Content

We are running a Shopify store, and have come to a point where we need more flexibility content wise. My solution to this is to have content delivered via a custom CMS to a subdomain. One issue I have is getting cart content from the primary domain on Shopify to the Sveltekit solution on the subdomain (I need to show the cart items count in the header, and also a list of the items in the cart in a sidebar).

Unfortunately just fetching the cart.json gives a CORS error. I have found a solution using JSONP:

function getCartData(data){
  /* do something with the data. In this example we are just loggin it */
  console.log(data)
}

var script = document.createElement('script');
script.src = 'https://jasons-experiments.myshopify.com/cart.json?callback=getCartData'
document.getElementsByTagName('head')[0].appendChild(script);

from this site: https://freakdesign.com.au/blogs/news/get-cart-contents-via-jsonp.

I am really stumped on how to do something like this from Sveltekit. Is this even possible?

2

Answers


  1. Chosen as BEST ANSWER

    Finally figured it out. In a blogpost from Logrocket, they try to explain the workings of JSONP. Probably succeeds as well, perhaps I just need to read it again. Anyway, I exctracted the function in their example and created a component in Svelte called getCartData.js:

    let jsonpID = 0;
    
    function jsonp(timeout = 7500) {
      const url = 'https://shopdomain.net/cart.json';
      const head = document.querySelector('head');
      jsonpID += 1;
    
      return new Promise((resolve, reject) => {
        let script = document.createElement('script');
        const callbackName = `jsonpCallback${jsonpID}`;
    
        script.src = encodeURI(`${url}?callback=${callbackName}`);
        script.async = true;
    
        const timeoutId = window.setTimeout(() => {
          cleanUp();
    
          return reject(new Error('Timeout'));
        }, timeout);
    
        window[callbackName] = data => {
          cleanUp();
    
          return resolve(data);
        };
    
        script.addEventListener('error', error => {
          cleanUp();
    
          return reject(error);
        });
    
        function cleanUp() {
          window[callbackName] = undefined;
          head.removeChild(script);
          window.clearTimeout(timeoutId);
          script = null;
        }
    
    
        head.appendChild(script);
      });
    }
    
    export default jsonp
    

    And in my header component, I just awaited the result:

    import jsonp from '$lib/helpers/getCartData';
    import { onMount } from 'svelte';
    
    let cartData = jsonp();
    
    onMount(async () => {
        console.log(await cartData);
    })
    

  2. Since you are not doing anything with secrets or API calls, and just want to send JSON to some foreign domain you control, just set your server there to be CORS-friendly and you can then make XHR calls to it without triggering CORS exceptions. Usually this is a very easy mod for you to make to your server.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search