Skip to main content

Framework integrations

React

While React is yet to improve their Web Component support in version 19 (https://github.com/facebook/react/issues/11347#issuecomment-1122275286) the current solution requires a simple workaround to assure critical Widget parameters are set on init.

The Widget wrapper and useEffect:

let scriptLoaded = false;

function FluidWrapper({ open, transaction, bonuses, onInfo, onCommand, onError }) {
const ref = useRef(null);

useEffect(() => {
let script;
if (window && document && !scriptLoaded) {
script = document.createElement('script');
script.src = 'https://get.fluidpayments.io/index.js';
script.async = true;
script.onload = () => {
console.log('Fluid script loaded');
};
document.head.appendChild(script);

scriptLoaded = true;
}

return () => {
if (script) {
script.remove();
}
};
}, []);

useLayoutEffect(() => {
const fluid = ref.current;

fluid.addEventListener('fluid-command', onCommand);
fluid.addEventListener('fluid-info', onInfo);
fluid.addEventListener('fluid-error', onError);

return () => {
fluid.removeEventListener('fluid-command', onCommand);
fluid.removeEventListener('fluid-info', onInfo);
fluid.removeEventListener('fluid-error', onError);
}
}, [onCommand, onError, onInfo, ref]);

return (
<fluid-widget
ref={ref}
id="fluid-widget"
operator-id="10000001"
user-id="10001"
session-id=""
locale="en"
currency="EUR"
user-data={ JSON.stringify(userData) }
transaction={ transaction }
open={ open }
balance="1000"
withdrawable-balance="900"
selected-bonus=""
bonuses={ JSON.stringify(bonuses || []) }
deposit-limit=""
success-cta-link="">
</fluid-widget>
);
}

Mind the scriptLoaded is there to prevent React from loading the Widget script twice on render.

An example of possible integration use:

function App() {
const [open, setOpen] = useState(false);
const [transaction, setTransaction] = useState('deposit');
const [numberOfBonuses, setNumberOfBonuses] = useState(bonuses.length);

function deposit() {
setTransaction('deposit');
setOpen(true);
}

function withdraw() {
setTransaction('withdrawal');
setOpen(true);
}

function quickDeposit() {
setTransaction('quick-deposit');
setOpen(true);
}

function close() {
setOpen(false);
}

function onCommand(event) {
console.info(`%cFluid COMMAND: ${event.detail}`, 'color: lightgreen', event);

if (event.detail === 'close') {
close();
}
}

function onInfo(event) {
console.info(`%cFluid INFO: ${event.detail}`, 'color: cornflowerblue', event);
}

function onError(event) {
console.error(`Fluid ERROR: ${event.detail}`, event);
}

function changeNumberOfBonuses() {
const newNumberOfBonuses = numberOfBonuses - 1 < 0 ? 3 : numberOfBonuses - 1;
setNumberOfBonuses(newNumberOfBonuses);
console.log('Number of bonuses set to', newNumberOfBonuses);
}

return (
<>
<h1>
<img src="/logo-mark-light.png" alt="Fluid" width={48} style={{ marginRight: '1rem' }} />
Fluid
</h1>

<div style={{ marginBottom: '1rem' }}>
<button onClick={ deposit }>Deposit
</button>
</div>
<div style={{ marginBottom: '1rem' }}>
<button onClick={ withdraw }>
Withdrawal
</button>
</div>
<div style={{ marginBottom: '1rem' }}>
<button onClick={ quickDeposit }>
Quick Deposit
</button>
</div>

<div style={{ marginBottom: '1rem' }}>
<button onClick={ changeNumberOfBonuses }>
Change bonuses
</button>
</div>

<FluidWrapper
open={open}
transaction={transaction}
bonuses={bonuses.slice(0, numberOfBonuses)}
onInfo={ onInfo }
onCommand={ onCommand }
onError={ onError }
/>
</>
)
}

Complete code of the POC: https://github.com/soltechno/fluid-react-integration