React Hooks
@simplelogs/next ships a set of React hooks for common browser measurement patterns. All hooks require the Provider to be in the tree.
All hooks are "use client" — they must be called from client components.
usePageLoadTime(options?)
Measures the time from navigation start to full page load (or to the first appearance of a specific DOM element).
'use client';
import { usePageLoadTime } from '@simplelogs/next';
export function PageLoadTracker() {
usePageLoadTime({
touchpoint: 'perf/page-load',
key: 'home-page-load',
});
return null;
}
Place this component anywhere in the page. It runs once and records a single timing entry.
UsePageLoadTimeOptions
| Field | Type | Default | Description |
|---|---|---|---|
selector | string | — | CSS selector. When provided, measures time until this element first appears in the DOM. When omitted, measures to window.load. |
touchpoint | string | — | Touchpoint name |
key | string | — | Correlation key |
metadata | Record<string, unknown> | — | Extra metadata |
Without a selector — uses PerformanceNavigationTiming.loadEventEnd when available, falls back to Date.now() at the load event.
With a selector — uses a MutationObserver to detect the element's first appearance. Useful for measuring "time to interactive" for a specific UI region.
useComponentMountTime(options?)
Records the time from navigation start to when the component first mounts. Useful for measuring how long it takes for a critical component to render.
'use client';
import { useComponentMountTime } from '@simplelogs/next';
export function ProductGrid({ products }) {
useComponentMountTime({
touchpoint: 'perf/product-grid-mounted',
metadata: { count: products.length },
});
return <div>{/* ... */}</div>;
}
UseComponentMountTimeOptions
| Field | Type | Description |
|---|---|---|
touchpoint | string | Touchpoint name |
key | string | Correlation key |
metadata | Record<string, unknown> | Extra metadata |
useTimedCallback(callback, options?)
Wraps any async or sync callback and automatically records how long each invocation takes. The timing is recorded even if the callback throws — the error is re-thrown after recording, with { error: true } merged into the metadata.
'use client';
import { useTimedCallback } from '@simplelogs/next';
export function SubmitButton({ onSubmit }) {
const timedSubmit = useTimedCallback(onSubmit, {
touchpoint: 'ui/form/submit',
key: 'checkout-submit',
});
return <button onClick={timedSubmit}>Submit</button>;
}
useTimedCallback returns a new async function with the same argument signature. It wraps the callback with useCallback, so you should pass a stable reference to avoid unnecessary re-renders (or add the callback to useMemo).
UseTimedCallbackOptions
| Field | Type | Description |
|---|---|---|
touchpoint | string | Touchpoint name |
key | string | Correlation key |
metadata | Record<string, unknown> | Extra metadata (merged with { error: true } on failure) |
useWebVitals(options)
Monitors a single Core Web Vital via PerformanceObserver. Silently no-ops if the vital is not supported by the current browser.
'use client';
import { useWebVitals } from '@simplelogs/next';
export function WebVitalsTracker() {
useWebVitals({ vital: 'lcp', touchpoint: 'perf/lcp', key: 'home-lcp' });
useWebVitals({ vital: 'fcp', touchpoint: 'perf/fcp', key: 'home-fcp' });
useWebVitals({ vital: 'ttfb', touchpoint: 'perf/ttfb', key: 'home-ttfb' });
useWebVitals({ vital: 'cls', touchpoint: 'perf/cls', key: 'home-cls' });
return null;
}
Supported vitals
| Value | Vital | Measurement |
|---|---|---|
"lcp" | Largest Contentful Paint | Recorded as a timing (ms from navigation start) |
"fcp" | First Contentful Paint | Recorded as a timing (ms from navigation start) |
"ttfb" | Time to First Byte | Recorded as a timing (response start ms) |
"cls" | Cumulative Layout Shift | Accumulated and flushed as a log entry with { cls: number } in metadata on unmount |
CLS is a score (0–∞), not a duration, so it is recorded as a log event rather than a timing entry. metadata.cls contains the cumulative score.
UseWebVitalsOptions
| Field | Type | Required | Description |
|---|---|---|---|
vital | "fcp" | "lcp" | "ttfb" | "cls" | Yes | Which vital to observe |
key | string | No | Correlation key |
touchpoint | string | No | Touchpoint name |
metadata | Record<string, unknown> | No | Extra metadata |
useSimpleLogs()
Returns the client logger singleton. Use this when you need direct access to log(), start(), end(), or record() inside a component.
const logger = useSimpleLogs();
See Client Logging for the full method reference.