Vue.js Integration Guide

Install IssueCapture in Vue.js

Add bug reporting to your Vue 3 application in 5 minutes. Works with Vite, Composition API, and Vue Router.

Quick Summary

  • Time: 2-5 minutes (7 simple steps)
  • Prerequisites: Vue 3+, Vite, Jira account, IssueCapture account (free)
  • Method: Script tag in index.html or programmatic onMounted
  • Works with: Vue 3, Vite, Vue Router, Pinia, Composition API
  • Bundle size: 32KB initial (152KB for screenshot & annotation tools, lazy-loaded)

Prerequisites

  • Vue 3 or higher (Composition API)
  • Vite (recommended build tool for Vue 3)
  • Jira Cloud account (Software or JSM)
  • IssueCapture account (sign up free)

Step-by-Step Installation

1

Get Your API Key

Sign up for IssueCapture and retrieve your widget API key from the dashboard

  • Go to https://issuecapture.com/signup and create a free account
  • Connect your Jira instance via OAuth
  • Navigate to the Widgets page and create a new widget
  • Copy your API key (starts with "ic_")
2

Add Environment Variable

Store your API key in your environment configuration

  • Vue 3 + Vite: Use VITE_ prefix for all environment variables
  • Create .env file in your project root
  • Never commit .env files to version control
  • Restart dev server after adding environment variables
# .env (Vite - recommended)
VITE_ISSUECAPTURE_API_KEY=ic_your_api_key_here

# Note: Vue 3 + Vite is the recommended setup
# Environment variables MUST start with VITE_ prefix
3

Install via Script Tag (Recommended)

Add IssueCapture to your index.html file

  • Place script tag at the end of <body> for optimal loading
  • Vite automatically replaces %VITE_*% tokens at build time
  • type="module" is required for ESM imports
  • Widget loads after Vue app initializes
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Your Vue App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>

    <!-- IssueCapture Widget -->
    <script type="module">
      import IssueCapture from 'https://issuecapture.com/widget.js';

      IssueCapture.init({
        apiKey: '%VITE_ISSUECAPTURE_API_KEY%',
        trigger: 'auto',
        button: {
          position: 'bottom-right',
          text: 'Report Bug'
        }
      });
    </script>
  </body>
</html>
4

Alternative: Programmatic Initialization

Initialize IssueCapture from your Vue component using onMounted

  • Loads widget only when component mounts
  • Use import.meta.env for Vite environment variables
  • Cleanup function destroys widget on unmount
  • Useful for single-page applications with Vue Router
<!-- src/App.vue -->
<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue'

onMounted(() => {
  // Dynamically load IssueCapture widget
  const script = document.createElement('script')
  script.type = 'module'
  script.innerHTML = `
    import IssueCapture from 'https://issuecapture.com/widget.js';

    IssueCapture.init({
      apiKey: '${import.meta.env.VITE_ISSUECAPTURE_API_KEY}',
      trigger: 'auto',
      button: {
        position: 'bottom-right',
        text: 'Report Bug'
      }
    });
  `
  document.body.appendChild(script)
})

onUnmounted(() => {
  // Cleanup on unmount
  if (window.IssueCapture) {
    window.IssueCapture.destroy()
  }
})
</script>

<template>
  <div id="app">
    <h1>Your Vue Application</h1>
    <!-- Your components -->
  </div>
</template>
5

Custom Trigger Component

Create a Vue component to trigger the widget

  • Use window.IssueCapture.open() to open programmatically
  • Check if IssueCapture exists before calling
  • Add aria-label for accessibility
  • Integrate into navbar, footer, or error handlers
<!-- src/components/BugReportButton.vue -->
<script setup lang="ts">
const openWidget = () => {
  if (window.IssueCapture) {
    window.IssueCapture.open()
  }
}
</script>

<template>
  <button
    @click="openWidget"
    class="bug-report-btn"
    aria-label="Report a bug"
  >
    Report Bug
  </button>
</template>

<style scoped>
.bug-report-btn {
  padding: 0.5rem 1rem;
  background: #42b883;
  color: white;
  border: none;
  border-radius: 0.5rem;
  cursor: pointer;
  font-weight: 600;
}

.bug-report-btn:hover {
  background: #35a372;
}
</style>

<!-- Usage in your app:
<script setup>
import BugReportButton from './components/BugReportButton.vue'
</script>

<template>
  <BugReportButton />
</template>
-->
6

Set User Context (Optional)

Pre-fill user information for authenticated users

  • Pre-fill reporter name and email for authenticated users
  • Use watch() to update user context when auth state changes
  • Component field maps to Jira components for routing
  • Improves bug report context for developers
<!-- src/App.vue -->
<script setup lang="ts">
import { ref, watch, onMounted } from 'vue'
import { useAuth } from './composables/useAuth' // Your auth composable

const { user } = useAuth()

onMounted(() => {
  // Initial setup
  if (window.IssueCapture && user.value) {
    updateUserContext()
  }
})

// Watch for user changes
watch(user, (newUser) => {
  if (window.IssueCapture && newUser) {
    updateUserContext()
  }
})

const updateUserContext = () => {
  window.IssueCapture.init({
    apiKey: import.meta.env.VITE_ISSUECAPTURE_API_KEY,
    trigger: 'auto',
    user: {
      name: user.value.name,
      email: user.value.email,
      component: 'Frontend' // Optional: Jira component
    }
  })
}
</script>

<template>
  <div id="app">
    <!-- Your app -->
  </div>
</template>
7

Test the Integration

Verify IssueCapture is working correctly

  • Start your dev server: npm run dev or pnpm dev
  • Open your app in the browser
  • You should see the floating bug report button
  • Click it and submit a test issue
  • Check your Jira project for the created issue
  • Open browser console and type: window.IssueCapture.isOpen()

Troubleshooting

TypeScript: Property 'IssueCapture' does not exist on type 'Window'

Add type declarations to your project:

// src/types/issuecapture.d.ts
interface IssueCaptureAPI {
  init(config: {
    apiKey: string
    trigger?: string | 'auto'
    button?: {
      position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'
      text?: string
      icon?: string
    }
    user?: {
      name?: string
      email?: string
      component?: string
    }
  }): void
  open(): void
  close(): void
  isOpen(): boolean
  destroy(): void
}

declare global {
  interface Window {
    IssueCapture?: IssueCaptureAPI
  }
}

export {}

Environment variables not working

  • Vite: Must use VITE_ prefix for all environment variables
  • Access via import.meta.env.VITE_YOUR_VAR (not process.env)
  • Restart dev server after adding/changing .env
  • Ensure .env is in project root (same level as vite.config.ts)

Widget loads multiple times (Vue Router)

If using Vue Router, initialize widget once in root component:

// src/App.vue - Initialize once at root level
<script setup>
import { onMounted } from 'vue'

let isInitialized = false

onMounted(() => {
  // Initialize IssueCapture only once
  if (!isInitialized && !window.IssueCapture) {
    // Load script...
    isInitialized = true
  }
})
</script>

CORS errors when submitting issues

  • Add localhost:5173 (Vite default) to allowed domains in dashboard
  • Add production domain to allowed domains
  • Check IssueCapture dashboard → Widgets → Domains

Advanced Configuration

Event Listeners

IssueCapture.init({
  apiKey: import.meta.env.VITE_ISSUECAPTURE_API_KEY,
  trigger: 'auto',
  onOpen: () => {
    console.log('Widget opened')
  },
  onClose: () => {
    console.log('Widget closed')
  },
  onSubmit: (data) => {
    console.log('Issue submitted:', data)
    // Show success toast, etc.
  }
})

Error Handler Integration

Automatically open IssueCapture when errors occur:

// src/main.ts
import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)

app.config.errorHandler = (err, instance, info) => {
  console.error('Vue error:', err, info)

  // Open IssueCapture for error reporting
  if (window.IssueCapture) {
    window.IssueCapture.open()
  }
}

app.mount('#app')

Production Best Practices

  • Load widget asynchronously to avoid blocking
  • Use environment variables for API keys
  • Whitelist production domains in dashboard
  • Test on staging before deploying

Ready to get started?

Sign up for a free account and start collecting bug reports in your Vue app in minutes.