Framer WhatsApp Widget: Embed Component and CTA
Framer WhatsApp widget can be added three ways: a free-form component with an Override, a Custom Code component for fully controlled behavior, and a CMS-driven phone number pulled from Framer CMS. Target link: wa.me/966500000000.
1. Framer embed via Override
Drag a new Component onto the canvas. Inside the component add a Link element. In the right-hand panel:
- URL:
https://wa.me/966500000000?text=Hi%2C%20I%27d%20like%20to%20know%20more%20about%20Wutt. - Open in: New Tab
- Style: 60×60 circle,
#25D366, fixed, bottom-right, z-index high - Add an SVG of the WhatsApp glyph as the link's child
For a re-usable widget, convert the component to a Component with Overrides. Promote the URL, label, and color to Overrides so designers can drop it on multiple pages with different phone numbers and copy.
2. Custom Code component
Drop a Code Component (or an HTML Embed) on the canvas. Paste:
import { addPropertyControls, ControlType } from "framer";
export default function WuttWhatsApp(props) {
const phone = (props.phone || "966500000000").replace(/\D/g, "");
const message = props.message || "Hi, I'd like to know more about Wutt.";
const label = props.label || "Chat";
const href = `https://wa.me/${phone}?text=${encodeURIComponent(message)}`;
return (
<a
href={href}
target="_blank"
rel="noopener"
style={{
position: "fixed",
right: 20, bottom: 20, zIndex: 9999,
width: 60, height: 60, borderRadius: "50%",
background: "#25D366", color: "#fff",
display: "flex", alignItems: "center", justifyContent: "center",
boxShadow: "0 10px 30px rgba(0,0,0,.25)",
textDecoration: "none", fontWeight: 700
}}
>
<svg viewBox="0 0 32 32" width="32" height="32" aria-hidden="true">
<path fill="#fff" d="M16 3C9 3 3.5 8.5 3.5 15.5c0 2.4.7 4.7 1.9 6.7L3 29l7-1.8c1.9 1 4 1.5 6 1.5 7 0 12.5-5.5 12.5-12.5S23 3 16 3z"/>
</svg>
<span style={{ marginLeft: 8 }}>{label}</span>
</a>
);
}
addPropertyControls(WuttWhatsApp, {
phone: { type: ControlType.String, title: "Phone", defaultValue: "966500000000" },
message: { type: ControlType.String, title: "Message", defaultValue: "Hi, I'd like to know more about Wutt." },
label: { type: ControlType.String, title: "Label", defaultValue: "Chat" },
});
Publish the site, drop the component on your canvas, and tweak the overrides in the right-hand panel. Designers can hand the file off to marketers with zero code involvement.
3. CMS-driven phone number from Framer CMS
Create a Framer CMS collection called Locations with fields Name (Title), Phone (Plain Text), and IsDefault (Boolean). Bind the component's phone Override to the collection's default item:
import { useCMSItem } from "framer";
export default function WuttCMS(props) {
const item = useCMSItem("Locations", item => item.IsDefault === true);
const phone = (item?.Phone || "966500000000").replace(/\D/g, "");
const message = `Hi, this is regarding ${item?.Name || "your business"}.`;
const href = `https://wa.me/${phone}?text=${encodeURIComponent(message)}`;
return (
<a href={href} target="_blank" rel="noopener"
style={{ background: "#25D366", color: "#fff", padding: "12px 18px",
borderRadius: 999, textDecoration: "none", fontWeight: 700 }}>
Chat with {item?.Name || "us"}
</a>
);
}
For per-page branches, pass the page slug into a CMS query and resolve the matching location. Each branch page can have its own phone without duplicating the component.
Notes
- Framer-published sites run React under the hood, so any prop you expose in
addPropertyControlsbecomes a designer-friendly override. - Use
position: fixedand a highzIndexso the button stays above Framer's own modals and announcement bars. - For animated badge or pulse, attach a Framer variant with a looping opacity animation.
Add Wutt to your site — start $1 trial
Drop the widget in, then keep every reply, click, lead, and order inside Wutt Inbox, Wutt Book, Wutt Reviews, Wutt Loyalty, and the CRM follow-up workspace.
Start $1 trial