Skip to content
Advertisement

Gatsby 3rd party scripts not working as intended

I have the problem with including fastspring to my gatsby project. Problem is the following: I add the script in html head but it doesn’t work on all pages(it works only if I refresh the page) I tried to fix that by inserting script in html.js, with gatsby-ssr.js and gatsby-browser.js

gatsby-browser.js enter image description here

I put the same code in gatsby-ssr.js, I have also tried with Helmet but nothing works for me I want it to work on all the pages without needing to refresh the page, so if somebody could help me with this. Thanks in advance! 🙂

Advertisement

Answer

Seems like an old issue, but someone might still have the problem. I did search for a solution to it for some time and in the end, I went with the following.

  1. I created a component called FastSpringStoreApi.js. It loads FastSpring API and subscribes to 2 callback events from it – data-popup-closed and data-data-callback. I used this two to dispatch custom js events for which I listen in my FastSpring provider. These 2 events contain all information needed for store to function (items, pricing, cart information)

Note: there is a reason I save data into sessionStorage. The event can be dispatched before React hydrates. And in cases like this I take data in session storage as initial state in my reducers.

import React from 'react';
import {
  FS_EVENTS,
  FS_SESSION_KEY
} from './FastSpringStore.keys';

export default ({ storeFrontId }) => (
  <>
    <script
      type="text/javascript"
      dangerouslySetInnerHTML= {{
        __html:`
          function raiseFSPopupCloseEvent(data) {
            var popupCloseEvent = new CustomEvent(
             '${FS_EVENTS.POPUP_CLOSE}',
             { detail: data }
            );
            window.dispatchEvent(popupCloseEvent);
          }
          
          function raiseFSDataUpdateEvent(data) {
            var dataUpdateEvent = new CustomEvent(
             '${FS_EVENTS.DATA_UPDATE}',
             { detail: data }
            );
            
            window
              .sessionStorage
              .setItem(
                '${FS_SESSION_KEY}',
                 JSON.stringify(data)
               )
              
            window.dispatchEvent(dataUpdateEvent);
          }
        `
      }}
    />
    <script
      id="fsc-api"
      src="https://d1f8f9xcsvx3ha.cloudfront.net/sbl/0.8.5/fastspring-builder.min.js"
      type="text/javascript"
      data-popup-closed="raiseFSPopupCloseEvent"
      data-data-callback="raiseFSDataUpdateEvent"
      data-continuous="true"
      data-storefront={storeFrontId}
    />
  </>
)
  1. I load this component inside gatsby-ssr.js only
export const onRenderBody = ({ setHeadComponents }) => {
  setHeadComponents([
    <FastSpringStoreApi
      key="fast-spring-store-api"
      storeFrontId="..."
    />,
  ])
}
  1. I have FasSpringStore provider where I subscribe to my fs events. Looks like this. With it I can get all data needed further down to any of the components.
useEffect(() => {
    const onPopupClosed = (data) => {
      // Popup was closed and order was finished (we have order id)
      if (_has(data.detail, 'id')) {
        // Navigate to home page
        // TODO: Show thank you page in the future
        navigate('/')
        dispatch(cleanShopStore())
      }
    }

    const onDataUpdate = (data) => {
      dispatch(
        setOrderInfo(
          mapFSDataToPayload(
            data.detail
          )
        )
      )
    }

    window.addEventListener(FS_EVENTS.POPUP_CLOSE, onPopupClosed, false);
    window.addEventListener(FS_EVENTS.DATA_UPDATE, onDataUpdate, false);


    return () => {
      window.removeEventListener(FS_EVENTS.POPUP_CLOSE, onPopupClosed)
      window.removeEventListener(FS_EVENTS.DATA_UPDATE, onDataUpdate)
      window.sessionStorage.removeItem(FS_SESSION_KEY)
    }
  }, [])
  1. Inside gatsby-ssr.js I wrap my root element with store provider
export const wrapRootElement = ({ element }) => (
  <FastSpringStoreProvider>
    {element}
  </FastSpringStoreProvider>
);
  1. Same goes for gatsby-browser.js
export const wrapRootElement = ({ element }) => (
  <FastSpringStoreProvider>
    {element}
  </FastSpringStoreProvider>
);

Hope this gives some ideas for FastSpring implementation.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement