message.comDevelopers

Install live chat on Vue

Mount the message.com widget from the onMounted lifecycle hook in Vue 3. Works on Vite, Vue CLI, and any Vue shell that runs in a browser. Nuxt gets a dedicated client-only plugin.

Vue 3 with Vite

Drop the snippet into your root App.vue inside an onMounted hook. The guard by element ID prevents double-mounts during Hot Module Reload.

src/App.vue
<!-- src/App.vue -->
<script setup lang="ts">
import { onMounted } from "vue";

const WORKSPACE_ID = "YOUR_WORKSPACE_ID";

onMounted(() => {
  if (document.getElementById("message-widget-script")) return;
  const s = document.createElement("script");
  s.id = "message-widget-script";
  s.async = true;
  s.src = "https://app.message.com/widget.js";
  s.dataset.workspace = WORKSPACE_ID;
  document.head.appendChild(s);
});
</script>

<template>
  <RouterView />
</template>

Nuxt 3

Use a client-only plugin so the widget never tries to evaluate during SSR. The .client.ts suffix tells Nuxt to skip this file on the server.

plugins/message-widget.client.ts
// plugins/message-widget.client.ts
export default defineNuxtPlugin(() => {
  if (document.getElementById("message-widget-script")) return;
  const s = document.createElement("script");
  s.id = "message-widget-script";
  s.async = true;
  s.src = "https://app.message.com/widget.js";
  s.dataset.workspace = "YOUR_WORKSPACE_ID";
  document.head.appendChild(s);
});

Drop the file into plugins/. Nuxt auto-registers it. No nuxt.config.ts change needed.

Identify the user on sign-in

After your auth flow returns a session, identify the visitor. Compute the HMAC userHash server-side. See Identify logged-in users.

IdentifyOnSignIn.vue
<!-- src/components/IdentifyOnSignIn.vue -->
<script setup lang="ts">
import { onMounted } from "vue";

const props = defineProps<{
  user: { email: string; name: string; id: string; userHash: string };
}>();

declare global {
  interface Window {
    Message?: { identify: (p: Record<string, unknown>) => void };
    MessageOnReady?: () => void;
  }
}

onMounted(() => {
  const identify = () => window.Message?.identify({
    email: props.user.email,
    name: props.user.name,
    userId: props.user.id,
    userHash: props.user.userHash,
  });
  if (window.Message) identify();
  else window.MessageOnReady = identify;
});
</script>

<template></template>

Push route changes

Watch $route (Options API) or use watch on useRoute() (Composition API). On each change, call window.Message?.update({ pageUrl: window.location.href }) so agents see the visitor's current page.

Verify the install

  1. Run npm run dev.
  2. Open the app in a private window.
  3. The launcher appears in the bottom-right within two seconds.
  4. Open the browser console. Confirm the [message] startup log.
  5. Send a test message. The conversation lands in app.message.com.

Common pitfalls

  • SSR crash. If you put the snippet outside onMounted in a Nuxt app, the server-render step throws on document. Use .client.ts plugins or guard with if (process.client).
  • HMR double-mount. Vite's HMR will remount components. The element-ID dedupe prevents two scripts loading.
  • Vue 2 projects. The pattern is the same with the mounted lifecycle. Composition API is not required.

Next steps