Widget

Hey everyone! Looks like you’re interested in integration Maqpie chat into your product. Setup wizard in our admin portal helps to install chat quick and easy in many cases but we also get questions about integration with Single Page Applications. This article should make it clear. We chose React as a framework for this guide.

Let’s start with loading and initializing the widget. Basically below is the snippet from the setup wizard, just wrapped into the react component. Here we define user data and chat settings and make some magic that lets us call methods of public api of chat immediately even if the widget isn’t loaded yet.
maqpie.js
import React from 'react';
const METHODS = [
'renderLargeView',
'showLargeView',
'destroyLargeView',
'subscribe',
'unsubscribe',
];
export default function MaqpieWidget({ appId, user, userHash, headerColor, scrollColor }) {
React.useEffect(() => {
if (appId && user) {
window.MP = { // you can find all fields in setup wizard in admin portal
data: {
appId,
user,
userHash,
},
settings: {
styles: {
headerColor, // a primary chat color
scrollColor, // a color of the chat scroll
},
},
};
window.MP._queue = window.MP._queue || [];
METHODS.forEach((method) => {
window.MP[method] = (...args) => {
const data = [method, ...args];
window.MP._queue.push(data);
};
});
let script = document.querySelector('script[src="https://widget.maqpie.com/widget/v1.0"]');
if (script) {
return;
}
script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.src = 'https://widget.maqpie.com/widget/v1.0';
document.body.append(script);
}
}, [appId, user, userHash, headerColor, scrollColor]);
return null;
}
Then we use our sweet component somewhere in application. We recommend to use it as close to root component as possible to avoid unnecessary renderings.
App.js
<Maqpie
appId="your_app_id"
user={{
username: 'John Doe',
firstName: 'John',
lastName: 'Doe',
email: 'john@demo.com',
userId: 'testUser1',
}}
/>
That’s it! Pretty straightforward, isn’t it?
But what if a small widget is not enough and you want to embed chat that should fit the size of the page?
Embedded mode

Let’s change a bit our wrapper component.
maqpie.js
export default function MaqpieWidget({ appId, user, userHash, headerColor, scrollColor, embedded }) {
React.useEffect(() => {
if (appId && user) {
window.MP = { // you can find all fields in setup wizard in admin portal
data: {
appId,
user,
userHash,
},
settings: {
styles: {
headerColor, // a primary chat color
scrollColor, // a color of the chat scroll
},
// here we say Maqpie to be embedded
mode: embedded ? 'embedded' : undefined,
},
};
window.MP._queue = window.MP._queue || [];
METHODS.forEach((method) => {
window.MP[method] = (...args) => {
const data = [method, ...args];
window.MP._queue.push(data);
};
});
let script = document.querySelector('script[src="https://widget.maqpie.com/widget/v1.0"]');
if (script) {
return;
}
script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.src = 'https://widget.maqpie.com/widget/v1.0';
document.body.append(script);
// initialize embedded chat
if (embedded) {
window.MP.renderLargeView('maqpie-chat');
window.MP.showLargeView();
// clean up resources when user leave page (component umnount)
return () => {
window.MP.destroyLargeView();
};
}
}
}, [appId, user, userHash, headerColor, scrollColor, embedded]);
// and add root component for our chat
return (
<div id="maqpie-chat">
</div>
);
}
And of course update the parent component.
App.js
<Maqpie
appId="your_app_id"
user={{
username: 'John Doe',
firstName: 'John',
lastName: 'Doe',
email: 'john@demo.com',
userId: 'testUser1',
}}
embedded
/>
Cool! Can I add a badge with number of unread messages to menu?
Sure! You can subscribe to unreadMessagesCountChanged
event and keep your site in sync with Maqpie. I'll use React's state for this example but you can do it with your favourite state management tool like Redux or Mobx. The trick here is that we need to subscribe after we initialize our chat. So, let's do one more change to our maqpie.js
file.
maqpie.js
export default function MaqpieWidget({ appId, user, userHash, headerColor, scrollColor, embedded, onMessageCountChange }) {
React.useEffect(() => {
if (appId && user) {
window.MP = { // you can find all fields in setup wizard in admin portal
data: {
appId,
user,
userHash,
},
settings: {
styles: {
headerColor, // a primary chat color
scrollColor, // a color of the chat scroll
},
// here we say Maqpie to be embedded
mode: embedded ? 'embedded' : undefined,
},
};
window.MP._queue = window.MP._queue || [];
METHODS.forEach((method) => {
window.MP[method] = (...args) => {
const data = [method, ...args];
window.MP._queue.push(data);
};
});
let script = document.querySelector('script[src="https://widget.maqpie.com/widget/v1.0"]');
if (script) {
return;
}
script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.src = 'https://widget.maqpie.com/widget/v1.0';
document.body.append(script);
// subscribe to unread messages count
if (onMessageCountChange) {
window.MP.subscribe('unreadMessagesCountChanged', onMessageCountChange);
}
// initialize embedded chat
if (embedded) {
window.MP.renderLargeView('maqpie-chat');
window.MP.showLargeView();
}
}
}, [appId, user, userHash, headerColor, scrollColor, embedded, onMessageCountChange]);
// and add root component for our chat
return (
<div id="maqpie-chat">
</div>
);
}
We've added onMessageCountChange
property. It must be a function that accepts single parameter - current number of unread messages. You might noticed that clean up code disappeared. I moved this part to App.js
file to make it work correctly because when we update state, React recreates children of this component and executes our clean up code. But don't worry, we won't reload the chat :) Let's have a look at the result.
App.js
function App() {
const [count, setCount] = React.useState(0);
React.useEffect(() => {
// clean up resources when user leave page (component umnount)
return () => {
window.MP.unsubscribe();
window.MP.destroyLargeView();
};
});
return (
<div className="App">
<div>Unread messages count: {count}</div>
<Maqpie
appId="your_app_id"
user={{
username: 'John Doe',
firstName: 'John',
lastName: 'Doe',
email: 'john@demo.com',
userId: 'testUser1',
}}
onMessageCountChange={setCount}
/>
</div>
);
}
Conclusion
So, we just added a fully functional chat into your application and it took about 10 minutes instead of months of development and testing. Nice performance :)
You can find the code of this example in our Github. Hope you find this article helpful and become our next big customer!