Install Flawsnap in an Angular app
Add the widget to src/index.html, then wrap the few calls you need in an injectable service so components never touch window directly.
Steps
- 1
Allow your hosts
In Flawsnap, add your production and staging domains and
localhost:4200(theng servedefault) under Security → Allowed domains. - 2
Add the snippet to src/index.html
Paste the snippet into the
<head>ofsrc/index.html. - 3
Create a FlawsnapService
Add a service that calls
window.Flawsnaponly in the browser. - 4
Identify users after sign-in
Call the service from your auth flow with the user’s name and email.
- 5
Serve and test
Run
ng serve, openlocalhost:4200and send a test report.
The snippet in src/index.html
index.html is the single page Angular boots into, so the widget loads once and stays for the session. It starts before Angular bootstraps, which means errors thrown while bootstrapping are in the report's console.
Do not add it to angular.json scripts. That bundles a copy of a file into your build, while this one is hosted and needs the data-key attribute on its own tag.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>MyApp</title>
<base href="/">
<script src="https://backend.flawsnap.com/widget.js" data-key="pk_…" async></script>
</head>
<body>
<app-root></app-root>
</body>
</html>The router and HttpClient
- Router. With the default path location strategy, every navigation updates the URL with the History API. Flawsnap follows that by itself, so you do not call anything per route. With
useHash: true(hash location), name screens from aNavigationEndsubscription withscreen(url). - HttpClient. Angular's
HttpClientmakes XHR orfetchrequests, and Flawsnap records the last 100 of both with method, URL, status and duration. Bodies are never captured, so tokens in request bodies stay out of reports.
A small service for the JS API
Keep window access in one place. The platform check makes the service safe under server-side rendering, where there is no window.
import { Injectable, PLATFORM_ID, inject } from '@angular/core'
import { isPlatformBrowser } from '@angular/common'
@Injectable({ providedIn: 'root' })
export class FlawsnapService {
private browser = isPlatformBrowser(inject(PLATFORM_ID))
identify(name: string, email: string) {
if (this.browser) window.Flawsnap?.identify({ name, email })
}
open() {
if (this.browser) window.Flawsnap?.open()
}
screen(name: string) {
if (this.browser) window.Flawsnap?.screen(name)
}
}Add the Window declaration from below to a .d.ts file in src, so this compiles.
The window declaration
// flawsnap.d.ts (anywhere your tsconfig includes)
export {}
declare global {
interface Window {
Flawsnap?: {
open(): void
identify(reporter: { name?: string; email?: string }): void
setMetadata(details: Record<string, unknown>): void
screen(name: string): void
track(name: string): void
resetUser(): void
}
}
}Opening the form from your own menu
Many Angular apps are internal tools with a help menu. Turn off Show on website (under Report a bug button) in the project settings and add a "Report a problem" item that calls flawsnap.open(). The form still captures the screenshot, console and network history of the page the user was on.
Troubleshooting
[flawsnap] widget disabled:onng serve: addlocalhost:4200, or the port you pass with--port.- TypeScript error
Property Flawsnap does not exist on type Window: the.d.tsfile is outside the folders yourtsconfigincludes. - A CSP in your server or
index.htmlmeta tag: allowhttps://backend.flawsnap.cominscript-srcandconnect-src. - Team sign-in popup cannot connect: the page’s
Cross-Origin-Opener-Policymust not besame-origin.
Questions
- Does Flawsnap work with Angular server-side rendering?
- Yes. The script only runs in the browser. Guard your own calls with
isPlatformBrowser, as in the service above. - Will zone.js interfere with the widget?
- The widget runs as a separate script and does not depend on Angular. It records requests at the browser level, so it sees calls made inside or outside Angular’s zone.
Try it on your own site
7-day free trial, then $9 a month for Starter or $19 for Pro, per organization, with unlimited team members.
Related
Updated