API
The composable, the hooks, and the page and link attributes.
usePrecog()
const { enabled, pause, resume, refresh, grantConsent, metrics, plan } = usePrecog();
| Member | What it does |
|---|---|
enabled | False while paused, or before consent when privacy.requireConsent is on. |
pause() | Stops predicting and removes the speculation rules. |
resume() | Starts again. |
refresh() | Predicts now, ignoring minIntervalMs. |
grantConsent() | Lets the module run when privacy.requireConsent is on. |
metrics | Counters, latency percentiles, hit rate and the estimated cost. |
plan | What is speculated right now, or null. |
pause() stays paused until you call resume(). A navigation will not undo it, which is a
deliberate change from an earlier version that silently resumed on every route change.On the server, and when the module is off, usePrecog() returns a no-op object, so a page can
call it unconditionally.
Per page
<script setup>
definePageMeta({ precog: false });
</script>
The module collects nothing and speculates nothing while this page is open, and picks up again when the visitor leaves it.
Per link
<template>
<NuxtLink to="/settings" data-precog="off">Never speculate this</NuxtLink>
<NuxtLink to="/pricing" data-precog="hint">Always a candidate, even off screen</NuxtLink>
</template>
Client hooks
nuxtApp.hook("precog:decision", (plan, trigger) => {
// trigger is 'route' | 'scroll' | 'pointer' | 'dom' | 'manual' | 'visible'
});
nuxtApp.hook("precog:metrics", (summary) => {
// summary.hitRate, summary.p95, summary.inputTokens, ...
});
A route change fires precog:decision with an empty plan, because the links the old plan named
are gone.
Server hooks
In a Nitro plugin:
server/plugins/precog.ts
export default defineNitroPlugin((nitro) => {
nitro.hooks.hook("precog:predict", (ctx) => {
// Read ctx.state, or set ctx.prediction to answer without calling Jev at all.
});
nitro.hooks.hook("precog:predicted", (ctx) => {
// Every fresh answer. ctx.substituted is true when it came from the hook above.
});
});
precog:predict is how the playground runs with no API key, and how you would swap in your own
model. precog:predicted is how it records real answers for replay.
A
precog:predicted listener that throws is ignored: the prediction already happened and the
visitor gets it. A precog:predict listener that throws fails the request, because that hook is
allowed to replace the answer.When a prediction fails, the endpoint answers 503 with an empty prediction and puts a short
reason in the x-precog-reason header. The client falls open either way.
Types
import type {
PrecogPlan,
PrecogPrediction,
PrecogState,
PrecogCandidate,
MetricsSummary,
} from "nuxt-precog";