Wafir is a lightweight feedback and issue reporting tool that seamlessly connects input from users and testers to your GitHub-based development workflow. It captures user input, screenshots, console logs, and essential browser telemetry to accelerate debugging. See details at https://bps-consulting.github.io/wafir/.
This repository contains everything needed to build, use, and support Wafir. You don't need to clone the repo to use Wafir: simply get the widget code and add it to your web application as described in the Quickstart Guide.
The repo includes source code for the following:
- Wafir Widget (packages/wafir): A web component built with Lit that you can embed in any web application to collect user feedback.
- Bridge Service (apps/bridge): A Fastify-based backend service that handles feedback submissions, file uploads, and GitHub integration. See the wafir-infrastructure repo for deployment and infrastructure details.
- Test Web Page (packages/wafir/index.html): A simple HTML page to test the Wafir widget in isolation.
- React Consumer (internal/react-consumer): A sample React application demonstrating how to integrate the Wafir widget. {TODO: Update or remove if needed}
- Framework Wrappers (packages/react, packages/vue): Sample React and Vue wrappers demonstrating how to integrate the Wafir widget into popular frameworks.
- Public Documentation Site (apps/www): An Astro-based website for public documentation deployed on GitHub Pages.
- Configuration Examples (examples/): Sample YAML files showing how to configure the Wafir widget.
- Lit: Simple, fast Web Components.
- Nanostores: A tiny state manager for React, Preact, Vue, Svelte, and vanilla JS.
- Modern Screenshot: Accurate DOM-to-Canvas rendering for feedback context.
- OpenAPI Fetch: Type-safe API fetching.
- Fastify: Fast and low overhead web framework for Node.js.
- Multi-destination Feedback Routing: Route user feedback, bug reports, and suggestions to multiple projects or repositories using the new
targetskey in your configuration. Screenshots and assets are routed via targets instead of a storage key.- Octokit: Integration with GitHub for automated issue creation. - Swagger/OpenAPI: Automated API documentation.
wafir/: The client-side widget built with Lit. It's designed to be embedded in any web application.bridge/: The backend server built with Fastify. It handles submissions, file uploads (to S3), and integrations (like GitHub).react-consumer/: A sample React application demonstrating how to integrate the Wafir widget.
This project is a monorepo managed by pnpm and Turborepo.
- Clone the repository:
git clone https://github.com/BPS-Consulting/wafir.git
cd wafir- Install dependencies:
pnpm installThe Wafir widget now routes feedback with a flexible targets: config blockβallowing routing to multiple destinations (projects/repos).
Migration from legacy storage config:
The legacy
storagekey configuration has been removed. All routing is now handled using thetargetsarray and form-leveltargetsreferences. To migrate, define each destination under thetargetskey, and update your forms to reference the appropriate target viatargets: [targetId].
title: "Contact Us"
targets:
- id: default
type: github/issues
target: your-username/your-repo
authRef: "YOUR_INSTALLATION_ID"
- id: project
type: github/project
target: your-username/your-project-id
authRef: "YOUR_INSTALLATION_ID"
forms:
- id: feedback
label: Feedback
icon: π
targets: [project] # Routes feedback to 'project' target
fields:
- id: rating
type: rating
attributes:
label: "How satisfied are you with our website?"
validations:
required: true
- id: description
type: textarea
attributes:
label: "What is the main reason for this rating?"
validations:
required: false
- id: issue
label: Issue
icon: π
targets: [default] # Routes feedback to 'default' target
fields:
- id: title
type: input
attributes:
label: "What issue did you encounter?"
validations:
required: true
- id: description
type: textarea
attributes:
label: "Additional information:"
validations:
required: trueSee
/examplesfor reference configs using the new targets paradigm.
To start the development environment for all packages (Widget, Bridge, and Consumer):
pnpm devThis command runs turbo run dev, which spins up:
- The Wafir Widget in watch mode.
- The Bridge API server.
- The React Consumer app to test the integration.
To build all packages for production:
pnpm buildTo build the browser version of the Wafir widget and copy it to the www site:
cd packages/wafir && pnpm run build:browser
cd apps/www && pnpm run buildCreate a .env file in the bridge/ directory based on the usage requirements. You typically need:
AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY: For S3 access.GITHUB_TOKEN: For GitHub issue creation integration.
The widget can be configured via attributes or JavaScript initialization. See the wafir/ directory for specific implementation details.
Wafir uses Shadow DOM for isolation but exposes CSS custom properties for theming. Set these on the wafir-widget element:
| Variable | Default | Description |
|---|---|---|
--wafir-font-family |
System fonts | Font stack |
--wafir-font-size |
14px |
Base font size |
--wafir-text-color |
#111827 |
Primary text color |
--wafir-text-secondary |
#6b7280 |
Muted text color |
--wafir-primary-color |
#2563eb |
Brand color |
--wafir-primary-hover |
#1d4ed8 |
Hover state |
--wafir-border-color |
#e5e7eb |
Border color |
--wafir-button-size |
48px |
Trigger button size |
--wafir-button-border-radius |
50% |
Button shape |
--wafir-button-offset |
20px |
Edge distance |
--wafir-button-icon-size |
24px |
Icon size |
--wafir-button-shadow |
0 4px 12px rgba(0,0,0,0.15) |
Button shadow |
--wafir-button-shadow-hover |
0 6px 16px rgba(0,0,0,0.2) |
Hover shadow |
--wafir-tooltip-bg |
#1f2937 |
Tooltip background |
--wafir-backdrop-color |
rgba(0,0,0,0.5) |
Modal backdrop |
--wafir-modal-bg |
white |
Modal background |
--wafir-modal-border-radius |
12px |
Modal corners |
--wafir-modal-max-width |
800px |
Modal width |
--wafir-modal-padding |
20px |
Modal spacing |
--wafir-modal-shadow |
0 20px 60px rgba(0,0,0,0.3) |
Modal shadow |
--wafir-modal-title-font-size |
18px |
Title size |
--wafir-modal-title-font-weight |
600 |
Title weight |
--wafir-modal-title-color |
--wafir-text-color |
Title color |
| Variable | Default | Description |
|---|---|---|
--wafir-form-text-color |
#374151 |
Form text |
--wafir-form-bg |
transparent |
Form background |
--wafir-form-padding |
20px |
Form padding |
--wafir-form-border-color |
#d1d5db |
Input borders |
--wafir-form-border-radius |
6px |
Input corners |
--wafir-form-input-padding |
10px 12px |
Input spacing |
--wafir-form-input-color |
#111827 |
Input text |
--wafir-form-input-bg |
#ffffff |
Input background |
--wafir-form-primary-color |
#2563eb |
Submit button |
--wafir-form-primary-hover |
#1d4ed8 |
Submit hover |
--wafir-form-disabled-color |
#9ca3af |
Disabled state |
--wafir-form-bg-secondary |
#f3f4f6 |
Secondary bg |
--wafir-form-bg-tertiary |
#f9fafb |
Tertiary bg |
--wafir-form-text-secondary |
#6b7280 |
Secondary text |
--wafir-form-telemetry-bg |
#f9fafb |
Telemetry bg |
--wafir-form-telemetry-border |
#e5e7eb |
Telemetry border |
--wafir-form-logs-bg |
#111827 |
Logs background |
--wafir-form-logs-text |
#f3f4f6 |
Logs text |
--wafir-form-log-warn |
#fde047 |
Warning color |
--wafir-form-log-error |
#f87171 |
Error color |
| Variable | Default | Description |
|---|---|---|
--wafir-highlighter-overlay-bg |
rgba(0,0,0,0.1) |
Overlay bg |
--wafir-highlighter-primary-color |
#2563eb |
Border color |
--wafir-highlighter-highlight-bg |
rgba(37,99,235,0.1) |
Fill color |
wafir-widget {
--wafir-primary-color: #6366f1;
--wafir-primary-hover: #818cf8;
--wafir-modal-bg: #ffffff;
--wafir-text-color: #1f2937;
--wafir-form-border-radius: 8px;
}- Fork the repo
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- This project uses normalize.css v8.0.1 by Nicolas Gallagher, licensed under the MIT License.
Install:
npm install wafirImport and use in your project:
import { WafirWidget } from "wafir";
// Register/use wafir-widget as a custom element (see docs)- For module consumers, import from
wafir, styles fromwafir/styles/widget.css, etc.
Add to your HTML:
<script src="https://cdn.jsdelivr.net/npm/wafir/dist/browser/wafir.browser.js"></script>This exposes Wafir globally (e.g. window.WafirWidget).
Include styles from the CDN:
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/wafir/dist/browser/styles/wafir-widget.css"
/>- Use
<wafir-widget></wafir-widget>in your HTML as documented.
See full docs at GitHub Pages.