Before You Start
- Sign up at grivo.io and log in to your dashboard.
- Go to Conversations → Create Chat Inbox.
- Copy your Inbox Token - you'll paste it in the code below.
Quick Start - Plain HTML
Works on any website. Paste this snippet right before the closing </body> tag:
<!-- Add before closing </body> tag -->
<script>
(function(g,r,i,v,o){g.grivo=g.grivo||function(){
(g.grivo.q=g.grivo.q||[]).push(arguments)};
o=r.createElement('script');o.async=1;
o.src=v;r.head.appendChild(o);
})(window,document,'grivo','https://grivo.io/widget/grivo-widget.js');
grivo('init', { inboxToken: 'YOUR_INBOX_TOKEN' });
</script>That's it! A green chat bubble will appear in the bottom-right corner of your page.
The script is non-blocking, so your page renders first and the widget mounts after. You will not see a layout shift, and First Contentful Paint stays unaffected.
Why widget load order matters more than you think
Mobile site speed is a measurable conversion lever. Deloitte's mobile speed study found that a 0.1 second improvement in load time was associated with an 8.4% lift in retail conversions and a 9.2% lift in average order value.
Many older chat widgets load synchronously, which means the browser blocks page render until the chat script finishes downloading. The user sees a blank page longer; you pay for it in bounce. Grivo's loader is async by default - the page renders first, the widget arrives in the background, and First Contentful Paint stays where it would be without any chat at all.
Source: Deloitte, “Milliseconds Make Millions: Mobile Site Speed”
JavaScript Frameworks
Pick your framework below for a copy-paste snippet:
Browser minimums: ES2015 with native async/await, Promise, and Map. That covers every evergreen browser shipped after 2017. Internet Explorer 11 is not supported.
Using the App Router? Add the widget in your root layout.tsx so it loads on every page.
// app/layout.tsx (App Router)
import Script from 'next/script';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
{children}
{/* Grivo Chat Widget */}
<Script
id="grivo-loader"
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `
(function(g,r,i,v,o){g.grivo=g.grivo||function(){
(g.grivo.q=g.grivo.q||[]).push(arguments)};
o=r.createElement('script');o.async=1;
o.src=v;r.head.appendChild(o);
})(window,document,'grivo','https://grivo.io/widget/grivo-widget.js');
grivo('init', { inboxToken: 'YOUR_INBOX_TOKEN' });
`,
}}
/>
</body>
</html>
);
}PHP, Laravel & CMS Platforms
Add to your theme's footer.php or use the wp_footer hook.
<?php // header.php or footer.php (WordPress / PHP) ?>
<!-- Grivo Chat Widget -->
<script>
(function(g,r,i,v,o){g.grivo=g.grivo||function(){
(g.grivo.q=g.grivo.q||[]).push(arguments)};
o=r.createElement('script');o.async=1;
o.src=v;r.head.appendChild(o);
})(window,document,'grivo','https://grivo.io/widget/grivo-widget.js');
grivo('init', {
inboxToken: '<?php echo esc_attr(get_option("grivo_inbox_token")); ?>'
});
</script>
<?php
/**
* Alternatively, add via WordPress hook:
*
* // In functions.php
* function grivo_chat_widget() {
* $token = get_option('grivo_inbox_token', 'YOUR_INBOX_TOKEN');
* echo '<script>
* (function(g,r,i,v,o){g.grivo=g.grivo||function(){
* (g.grivo.q=g.grivo.q||[]).push(arguments)};
* o=r.createElement("script");o.async=1;
* o.src="https://grivo.io/widget/grivo-widget.js";
* r.head.appendChild(o);
* })(window,document,"grivo");
* grivo("init",{inboxToken:"' . esc_attr($token) . '"});
* </script>';
* }
* add_action('wp_footer', 'grivo_chat_widget');
*/
?>JavaScript API Reference
Control the widget programmatically after initialization:
// Open the chat widget programmatically
grivo('open');
// Close the chat widget
grivo('close');
// Completely remove the widget from the page
grivo('destroy');grivo('open')Open the chat window.
grivo('close')Minimize the chat window.
grivo('destroy')Remove widget from page entirely.
Identifying Logged-In Users
When you pass email and name during init, the widget automatically skips the pre-chat form and links conversations to the user's contact record. This means returning users see their full chat history.
// Identify logged-in users to skip pre-chat form
// and link conversations to their account
grivo('init', {
inboxToken: 'YOUR_INBOX_TOKEN',
email: currentUser.email, // User's email
name: currentUser.displayName // User's name
});Customization Options
You can customize the widget directly from the Grivo dashboard - no code changes needed:
Path: Dashboard → Conversations → your inbox → Widget Settings. Changes propagate to live sites in under a minute. No redeploy, no cache bust, no script swap.
Widget Color
Match your brand - pick any hex color from the inbox settings.
Welcome Message
Set a greeting shown when visitors open the chat for the first time.
Pre-Chat Form
Collect name & email before chat starts. Disable for logged-in users.
Allowed Domains
Restrict widget to specific domains for security. Leave empty for all.
Troubleshooting and FAQ
Widget bubble does not appear▼
Check that your Inbox Token is correct and the inbox is active. Open the browser console (F12) and look for [Grivo] error messages. Most missing-bubble cases are a typo in the token or a content security policy that blocks the script src.
Widget appears but no messages send▼
Verify your API URL is correct. If self-hosting, ensure CORS allows your website domain on the API server. Open the Network tab and watch for failed POST requests to /api/messages.
Widget conflicts with other scripts or sits behind other elements▼
Grivo uses an isolated namespace (window.grivo) so it will not collide with other vendors. Visually, the widget renders at z-index 2147483000 - if it still appears behind a sticky header or a modal, that element has an even higher z-index, and the fix is on your side, not on Grivo.
Pre-chat form keeps showing for returning visitors▼
The widget stores a session token in localStorage. If your site clears localStorage on each visit (privacy plugins or incognito mode), every visit looks like a new visitor. Pass email and name during init for logged-in users to bypass the pre-chat form entirely.
Can I open the chat programmatically when a user clicks a button?▼
Yes. After the widget loads, call grivo('open') from any click handler. Wire it to a help button, a CTA, or a keyboard shortcut. The widget keeps its state in sync, so a programmatic open registers the same way a bubble click does.
Does the widget slow down my page?▼
It loads asynchronously and weighs under 15KB gzipped, so it never blocks your page render. First contentful paint stays unaffected; the widget appears once the rest of the page is interactive. Time to first message after page load is typically under 200ms on a 4G connection.