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