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
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.
- I created a component called FastSpringStoreApi.js. It loads FastSpring API and subscribes to 2 callback events from it –
data-popup-closed
anddata-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} /> </> )
- I load this component inside
gatsby-ssr.js
only
export const onRenderBody = ({ setHeadComponents }) => { setHeadComponents([ <FastSpringStoreApi key="fast-spring-store-api" storeFrontId="..." />, ]) }
- 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) } }, [])
- Inside
gatsby-ssr.js
I wrap my root element with store provider
export const wrapRootElement = ({ element }) => ( <FastSpringStoreProvider> {element} </FastSpringStoreProvider> );
- Same goes for
gatsby-browser.js
export const wrapRootElement = ({ element }) => ( <FastSpringStoreProvider> {element} </FastSpringStoreProvider> );
Hope this gives some ideas for FastSpring implementation.