Getting Started

Migration Guide

Upgrade from nuxt-tawk-to v1 to v2. The inject/provide API is gone — use the new useTawk() composable instead.

Version 2 is a breaking change. The old Vue provide/inject pattern has been removed in favour of the new useTawk() composable, which is auto-imported across your entire app.

No changes are needed in nuxt.config.ts or to your install command. Only your component code needs updating.

What Changed

Featurev1v2
API accessinject('toggle')useTawk().toggle
Reactive state❌ Not availableisHidden, isMinimized, isMaximized, status, unreadCount
Event listeners❌ Not availableonLoad, onStatusChange, onChatStarted… (with cleanup)
TypeScriptPartialFull — all types exported via nuxt-tawk-to/types
Auto-importuseTawk() is globally available

Step-by-Step Migration

1. Remove inject calls

Find all inject(...) calls and replace them with useTawk():

// ❌ v1 — inject each function manually
import { inject } from 'vue'
const toggle = inject<() => void>('toggle')
const maximize = inject<() => void>('maximize')
const minimize = inject<() => void>('minimize')
const setAttributes = inject<(...args: any[]) => void>('setAttributes')
// ✅ v2 — one destructure, fully typed
const { toggle, maximize, minimize, setAttributes } = useTawk()

2. Update Component Code

Before (v1):

components/ChatControl.vue
<script setup lang="ts">
import { inject } from 'vue'

const toggle = inject<() => void>('toggle')

const handleChat = () => {
  if (toggle) toggle()
}
</script>

<template>
  <button @click="handleChat">Chat with us</button>
</template>

After (v2):

components/ChatControl.vue
<script setup lang="ts">
const { toggle } = useTawk()
</script>

<template>
  <button @click="toggle()">Chat with us</button>
</template>

3. Identify Visitors — Update the Pattern

Before (v1):

app.vue
<script setup lang="ts">
import { inject, onMounted } from 'vue'

const setAttributes = inject<(attrs: object, cb?: () => void) => void>('setAttributes')

onMounted(() => {
  if (setAttributes) {
    setAttributes({ name: 'John Doe', email: 'john@example.com' })
  }
})
</script>

After (v2):

app.vue
<script setup lang="ts">
const { visitor, setAttributes } = useTawk()

onMounted(() => {
  visitor({ name: 'John Doe', email: 'john@example.com' })
  setAttributes({ plan: 'Pro' })
})
</script>

4. Use Reactive State (New in v2)

v1 had no reactive state — you had to track widget state yourself. v2 provides it out of the box:

<script setup lang="ts">
// ✅ v2 — reactive refs, no manual tracking needed
const { isHidden, unreadCount, status, showWidget } = useTawk()
</script>

<template>
  <button v-if="isHidden" @click="showWidget()">
    Open Chat
    <span v-if="unreadCount > 0">({{ unreadCount }})</span>
  </button>
  <span>Agent status: {{ status }}</span>
</template>

5. Use Event Listeners (New in v2)

// ✅ v2 — subscribe to any event with auto-cleanup
const { onLoad, onChatStarted, onStatusChange } = useTawk()

onMounted(() => {
  const cleanups = [
    onLoad(() => console.log('Loaded')),
    onChatStarted(() => console.log('Chat started')),
    onStatusChange((status) => console.log('Status:', status))
  ]

  onUnmounted(() => cleanups.forEach(fn => fn()))
})

Removed Injection Keys

The following inject keys no longer exist. Use useTawk() instead:

v1 inject keyv2 equivalent
inject('toggle')useTawk().toggle
inject('maximize')useTawk().maximize
inject('minimize')useTawk().minimize
inject('hideWidget')useTawk().hideWidget
inject('showWidget')useTawk().showWidget
inject('setAttributes')useTawk().setAttributes
inject('addTags')useTawk().addTags
inject('endChat')useTawk().endChat