Install IssueCapture in Angular
Add bug reporting to your Angular application in 5 minutes. Works with Angular 15+, TypeScript, and standalone components.
Quick Summary
Prerequisites
- Angular 15 or higher
- TypeScript 4.9+
- Jira Cloud account (Software or JSM)
- IssueCapture account (sign up free)
Step-by-Step Installation
Follow these steps to get up and running in minutes.
Get Your API Key
Sign up for IssueCapture and retrieve your widget API key from the dashboard
- Go to 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_")
Add Environment Variable
Store your API key in your environment configuration
- Angular uses environment.ts for configuration
- Store different API keys for dev and production
- Never commit production keys to version control
- Angular CLI automatically uses the correct environment file
// src/environments/environment.ts
export const environment = {
production: false,
issueCaptureApiKey: 'ic_your_api_key_here'
};
// src/environments/environment.prod.ts
export const environment = {
production: true,
issueCaptureApiKey: 'ic_your_production_api_key'
};Install via Script Tag (Recommended)
Add IssueCapture to your src/index.html file
- Place script tag at the end of <body> for optimal loading
- type="module" is required for ESM imports
- For dynamic API keys, use programmatic initialization (Step 4)
- Widget loads after Angular app bootstraps
<!-- src/index.html -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Your Angular App</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
<!-- IssueCapture Widget -->
<script type="module">
import IssueCapture from 'https://issuecapture.com/widget.js';
// Note: Replace with actual API key during build
// Or use programmatic initialization (see Step 4)
IssueCapture.init({
apiKey: 'ic_your_api_key_here', // Replace with your API key
trigger: 'auto',
button: {
position: 'bottom-right',
text: 'Report Bug'
}
});
</script>
</body>
</html>Alternative: Programmatic Initialization
Initialize IssueCapture from your AppComponent using ngOnInit
- Loads widget when AppComponent initializes
- Uses environment.ts for API key management
- Cleanup in ngOnDestroy prevents memory leaks
- Useful for SPA with Angular Router
// src/app/app.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { environment } from '../environments/environment';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
title = 'your-angular-app';
ngOnInit(): void {
// 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: '${environment.issueCaptureApiKey}',
trigger: 'auto',
button: {
position: 'bottom-right',
text: 'Report Bug'
}
});
`;
document.body.appendChild(script);
}
ngOnDestroy(): void {
// Cleanup on destroy
if ((window as any).IssueCapture) {
(window as any).IssueCapture.destroy();
}
}
}Custom Trigger Component
Create an Angular component to trigger the widget
- Use (window as any).IssueCapture.open() to open programmatically
- Check if IssueCapture exists before calling
- Add aria-label for accessibility
- Integrate into navbar, footer, or error handlers
// src/app/components/bug-report-button/bug-report-button.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-bug-report-button',
template: `
<button
(click)="openWidget()"
class="bug-report-btn"
aria-label="Report a bug"
>
Report Bug
</button>
`,
styles: [`
.bug-report-btn {
padding: 0.5rem 1rem;
background: #dd0031;
color: white;
border: none;
border-radius: 0.5rem;
cursor: pointer;
font-weight: 600;
font-size: 1rem;
}
.bug-report-btn:hover {
background: #c3002f;
}
`]
})
export class BugReportButtonComponent {
openWidget(): void {
const issueCapture = (window as any).IssueCapture;
if (issueCapture) {
issueCapture.open();
}
}
}
// Usage in your template:
// <app-bug-report-button></app-bug-report-button>Set User Context (Optional)
Pre-fill user information for authenticated users
- Pre-fill reporter name and email for authenticated users
- Update user context when auth state changes
- Component field maps to Jira components for routing
- Improves bug report context for developers
// src/app/app.component.ts
import { Component, OnInit } from '@angular/core';
import { AuthService } from './services/auth.service'; // Your auth service
import { environment } from '../environments/environment';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
constructor(private authService: AuthService) {}
ngOnInit(): void {
// Subscribe to auth state changes
this.authService.user$.subscribe(user => {
if ((window as any).IssueCapture && user) {
this.updateUserContext(user);
}
});
}
private updateUserContext(user: any): void {
(window as any).IssueCapture.init({
apiKey: environment.issueCaptureApiKey,
trigger: 'auto',
user: {
name: user.name,
email: user.email,
component: 'Frontend' // Optional: Jira component
}
});
}
}Test the Integration
Verify IssueCapture is working correctly
- Start your dev server: ng serve
- 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
Common integration issues and how to solve them.
TypeScript: Property 'IssueCapture' does not exist on type 'Window'
Add type declarations to your project (src/types/issuecapture.d.ts)
- Create a type declaration file in src/types/issuecapture.d.ts
- Declare the global Window interface with IssueCapture property
- Export an empty object to make it a module
Environment files not being used
- Ensure environment.ts exists in src/environments/
- Check angular.json has correct fileReplacements configuration
- Import from '../environments/environment', not hardcoded paths
- Restart ng serve after changing environment files
Widget loads multiple times (Angular Router)
- Initialize widget once in AppComponent, not in child routes
- Use a private flag to track initialization status
- Check if window.IssueCapture exists before loading
Domain allowlist errors when submitting issues (often shown as CORS)
- Add localhost:4200 (Angular default) to allowed domains in dashboard
- Add production domain to allowed domains
- Check IssueCapture dashboard → Widgets → Domains
Ready to get started?
Sign up for a free account and start collecting bug reports in your Angular app in minutes.