Skip to content

React Integration

import { Aside } from ‘@astrojs/starlight/components’;

Create a shared client instance and use it across your app.

src/lib/gunsole.ts
import { createGunsoleClient } from "gunsole-js";
export const gun = createGunsoleClient({
projectId: "my-react-app",
apiKey: "dev",
mode: "local",
appName: "my-react-app",
appVersion: import.meta.env.VITE_APP_VERSION || "dev",
defaultTags: {
framework: "react",
},
});
// Attach global error handlers once
gun.attachGlobalErrorHandlers();

Import gun wherever you need it:

src/components/UserList.tsx
import { gun } from "../lib/gunsole";
import { useEffect, useState } from "react";
function UserList() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch("/api/users")
.then((res) => res.json())
.then((data) => {
setUsers(data);
gun.info({
bucket: "ui",
message: `Loaded ${data.length} users`,
tags: { component: "UserList", action: "fetch" },
});
})
.catch((err) => {
gun.error({
bucket: "ui",
message: "Failed to load users",
context: { error: err.message },
tags: { component: "UserList", action: "fetch" },
});
});
}, []);
return <ul>{users.map((u) => <li key={u.id}>{u.name}</li>)}</ul>;
}

If you’re initializing gunsole inside a component (not recommended, but possible):

useEffect(() => {
const client = createGunsoleClient({ ... });
return () => client.destroy();
}, []);

For the shared instance pattern, call gun.destroy() when your app is fully unmounting (rare in SPAs).

Track Core Web Vitals with gunsole:

import { onCLS, onFCP, onINP, onLCP, onTTFB } from "web-vitals";
import { gun } from "./lib/gunsole";
function reportWebVital(metric) {
gun.info({
bucket: "web_vitals",
message: `${metric.name}: ${metric.value.toFixed(2)}`,
context: {
value: metric.value,
rating: metric.rating,
delta: metric.delta,
navigationType: metric.navigationType,
},
tags: {
metric: metric.name,
rating: metric.rating,
},
traceId: metric.id,
});
}
onCLS(reportWebVital);
onFCP(reportWebVital);
onINP(reportWebVital);
onLCP(reportWebVital);
onTTFB(reportWebVital);

Log errors caught by React error boundaries:

import { Component } from "react";
import { gun } from "./lib/gunsole";
class ErrorBoundary extends Component {
componentDidCatch(error, errorInfo) {
gun.error({
bucket: "ui",
message: `React error boundary: ${error.message}`,
context: {
stack: error.stack,
componentStack: errorInfo.componentStack,
},
tags: { type: "error-boundary" },
});
}
render() {
// your fallback UI
}
}