Quick start
Once pet.js is installed, your pages get one global object, petMySite. There’s nothing else to load. If you haven’t installed the pet yet, follow the manual install guide first.
<script src="https://cdn.petmysite.com/pet.js" data-site="YOUR_SITE_KEY" async></script>
<script>
petMySite.showBubble("Free shipping ends tonight", "See the offer", "/offer");
petMySite.onClick((e) => console.log("Visitor clicked", e.pet.id));
</script>When you can call it
petMySite exists as soon as pet.js has run, so a script placed after it can call methods and add handlers straight away. Calls made while the pet is still loading wait and then run in order.
When you can’t control the order, for example with async or defer scripts, Google Tag Manager or a plugin that delays JavaScript, use the queue. It works whether it runs before or after pet.js:
<script>
(window.petMySiteQueue = window.petMySiteQueue || []).push(function (pet) {
pet.onClick(function (e) { /* … */ });
if (location.pathname.startsWith("/checkout")) pet.hide();
});
</script>Each function receives the same object as window.petMySite. Queued functions run as soon as pet.js starts, and later ones run straight away. To act only once the pet is visible, listen for the petmysite:ready window event.
If the pet can’t load (for example, the domain doesn’t match or your chat tool isn’t available), calls are quietly ignored and handlers never run. Your page keeps working as before.
Methods
Methods never throw. A call with invalid arguments logs a warning that starts with [PetMySite] in the browser console and does nothing.
petMySite.show()
Shows the pet again after hide(). While your chat window is open the pet stays out of the way, and it comes back when the chat closes.
petMySite.hide()
Hides the pet, its menu and any message. It isn’t remembered between pages, so call it on each page where the pet should stay hidden.
petMySite.showBubble(message, linkText?, action?, options?)
Shows a speech bubble next to the pet.
message: plain text, 1 to 160 characters. HTML is shown as text, not rendered.linkText: optional button label, up to 40 characters. It needs anaction.action: a web address (full, or relative to the current page) or a function to call. Onlyhttpandhttpsaddresses are accepted. WithoutlinkText, clicking the message runs the action.options.newTab: set totrueto open the address in a new tab. Addresses open in the same tab by default.
Your bubble replaces any Smart Bubble or invite message and stays until the visitor closes it, you call hideBubble(), or the visitor moves to another page. A Smart Bubble due on this page waits until yours closes. Nothing shows while the pet is hidden.
petMySite.hideBubble()
Closes a bubble you opened with showBubble().
petMySite.play(state)
Plays one of the pet’s animations: wave, celebrate, excited, surprised, curious, loved, look_around or peek. The pet returns to its normal behaviour afterwards.
Nothing plays while the pet is hidden, while a visitor is holding or stroking it, or when the visitor has asked their device to reduce motion.
petMySite.chatOpened()
Tells PetMySite that your own chat opened after a visitor used the pet, so it counts in your dashboard’s Actions. Count chats you open explains when it counts.
petMySite.open()
Does what a click on the pet does: opens your chat, or the contact menu when you have several click actions. Returns false if there’s nothing to open. It doesn’t fire a click event.
Events
Add a handler with petMySite.on(type, handler) or one of the shortcuts. Each returns a function that removes the handler; petMySite.off(type, handler) does the same.
onClick(handler) · on("click", handler)
The visitor clicked or tapped the pet, or pressed Enter or Space while it had focus. Runs before the pet opens your chat or menu, so you can cancel that.
onPetting(handler) · on("petting", handler)
The visitor finished petting the pet, by stroking it with the pointer or dragging a finger across it. Fires once per petting session.
onRightClick(handler) · on("rightClick", handler)
The visitor right-clicked the pet, or long-pressed it in a touch browser that opens menus that way, such as Chrome on Android. The browser’s menu doesn’t appear over the pet; instead it reacts with an animation that suits its mood. The rest of your page keeps its normal menu.
Every handler receives an event with type, pet.id (for example "piko"), pet.play(state), cancelable, defaultPrevented and preventDefault(). An error in one handler is reported in the console and doesn’t stop the pet or other handlers.
Replace the click action
Call e.preventDefault() in a click handler to stop the action set in your PetMySite dashboard, whether that’s your chat window or the contact menu, and run your own instead.
petMySite.onClick((e) => {
e.preventDefault(); // skip the configured chat or menu
e.pet.play("celebrate");
openMyOwnHelpPanel(); // your code
});Only click can be cancelled. Petting and right-click events are notifications.
Count chats you open
PetMySite counts a chat open by itself when the pet opens a chat tool it supports. When your own code opens the chat, for example with Trigger chat via API or a replaced click action, only your page knows the chat opened. Call petMySite.chatOpened() once it has:
petMySite.onClick((e) => {
e.preventDefault();
myChat.open(); // your chat tool
});
myChat.on("open", () => petMySite.chatOpened());It counts one chat open per pet click or bubble action, within a minute of it. Chats opened another way, and repeated calls, aren’t counted, so the number only shows chats the pet led to. Clicks on the pet are counted either way.
Examples
Celebrate an add to cart
document.querySelector("#add-to-cart").addEventListener("click", () => {
petMySite.play("celebrate");
petMySite.showBubble("Nice pick! Your cart is ready.", "Check out", "/checkout");
});Hide the pet on some pages
// Keep the checkout page quiet.
if (location.pathname.startsWith("/checkout")) petMySite.hide();Run your own code or open a new tab
petMySite.showBubble(
"Want a tour of the dashboard?",
"Start the tour",
() => startProductTour(),
);
petMySite.showBubble("Read our sizing guide", "Open guide", "https://example.com/sizes", {
newTab: true,
});Listen and stop listening
const stop = petMySite.onPetting(() => {
petMySite.showBubble("That tickles! Thanks for saying hi.");
});
petMySite.onRightClick(() => analytics.track("pet_right_click"));
stop(); // remove the petting handler againTypeScript
Add these declarations to your project to type window.petMySite. window.PetMySite is the same object.
type PetPlayState =
| "wave" | "celebrate" | "excited" | "surprised"
| "curious" | "loved" | "look_around" | "peek";
type PetEventType = "click" | "petting" | "rightClick";
interface PetEvent {
readonly type: PetEventType;
readonly pet: { readonly id: string; play(state: PetPlayState): void };
readonly cancelable: boolean; // true only for "click"
readonly defaultPrevented: boolean;
preventDefault(): void;
}
interface PetMySiteApi {
show(): void;
hide(): void;
showBubble(
message: string,
linkText?: string,
action?: string | (() => void),
options?: { newTab?: boolean },
): void;
hideBubble(): void;
play(state: PetPlayState): void;
open(): boolean;
chatOpened(): void;
on(type: PetEventType, handler: (event: PetEvent) => void): () => void;
off(type: PetEventType, handler: (event: PetEvent) => void): void;
onClick(handler: (event: PetEvent) => void): () => void;
onPetting(handler: (event: PetEvent) => void): () => void;
onRightClick(handler: (event: PetEvent) => void): () => void;
}
declare global {
interface Window {
petMySite: PetMySiteApi;
PetMySite: PetMySiteApi;
}
}Limits and privacy
- Events tell you what happened, never who did it. They include no pointer position, page content or visitor details.
- The API runs in the visitor’s browser. It can’t change your PetMySite settings, plan or attribution.
- Bubble text is always plain text, so visitor-supplied strings can’t inject markup through it.
Questions or ideas for the API? Email support@petmysite.com.