This guide shows you how to add Heyo to your Framer website. Works with all Framer projects and templates.
<script src="https://heyo.so/embed/script" defer data-project-id="YOUR_PROJECT_ID"></script>
For site-wide integration:
<script src="https://heyo.so/embed/script" defer data-project-id="YOUR_PROJECT_ID"></script>
Create a beautiful custom button in Framer to trigger the chat:
import { useEffect } from "react"
export default function ChatButton() {
const openChat = () => {
if (window.HEYO) {
window.HEYO.show()
}
}
return (
<button
onClick={openChat}
style={{
padding: "12px 24px",
background: "#6366f1",
color: "white",
border: "none",
borderRadius: "8px",
cursor: "pointer",
fontSize: "16px",
}}
>
Chat with us
</button>
)
}
Or use Framer's interactive capabilities:
<!-- Add to a Custom Code component -->
<script>
function openHeyoChat() {
window.HEYO?.show();
}
</script>
<button onclick="openHeyoChat()" style="padding: 12px 24px; background: #6366f1; color: white; border: none; border-radius: 8px; cursor: pointer;">
Need help?
</button>
If using a custom trigger, hide the default Heyo button:
<style>
#heyo-widget-button {
display: none !important;
}
</style>
Show/hide chat on specific pages:
// Code Component
import { useEffect } from "react"
import { useRouter } from "framer"
export default function HeyoControl() {
const router = useRouter()
useEffect(() => {
// Hide on pricing page
if (router.pathname === "/pricing") {
window.HEYO?.hide()
} else {
window.HEYO?.show()
}
}, [router.pathname])
return null
}
Pass CMS data to your chat widget:
// Code Component for CMS pages
export default function CMSHeyo({ title, author }) {
useEffect(() => {
if (window.HEYO) {
window.HEYO.trackEvent("viewing_content", {
title: title,
author: author,
})
}
}, [title, author])
return null
}
Heyo works seamlessly with Framer Motion animations. No conflicts!
Example of animating your custom chat button:
import { motion } from "framer-motion"
export default function AnimatedChatButton() {
return (
<motion.button
onClick={() => window.HEYO?.show()}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
style={{
padding: "12px 24px",
background: "#6366f1",
color: "white",
border: "none",
borderRadius: "8px",
cursor: "pointer",
}}
>
Chat with us
</motion.button>
)
}
For authenticated Framer sites, pass user context:
// Code Component
import { useEffect } from "react"
export default function HeyoWithUser({ userName, userEmail }) {
useEffect(() => {
if (window.HEYO) {
window.HEYO.init({
projectId: "YOUR_PROJECT_ID",
user: {
name: userName,
email: userEmail,
},
})
}
}, [userName, userEmail])
return null
}
Control widget visibility on different screen sizes:
<!-- Custom Code Component -->
<style>
@media (max-width: 768px) {
#heyo-widget-button {
bottom: 20px;
right: 20px;
}
}
</style>
For agencies:
If you're creating Framer templates:
Add type definitions:
declare global {
interface Window {
HEYO: {
show: () => void
hide: () => void
toggle: () => void
init: (config: any) => void
}
}
}