---
title: "Adding your app’s context"
description: "Attach what your app already knows, such as the signed-in user, the plan, the release and feature flags, to every Faylee recording with window.faylee.metadata()."
canonical: https://faylee.app/docs/capture/app-metadata
---

# Adding your app’s context

Your app knows things a recording cannot see: who is signed in, which plan they are on, which release is running, which feature flags are on. Pass them to Faylee once, and every recording, instant replay and screenshot taken on your app carries them.

## The call

When Faylee can capture a page, with the extension or the [site widget](https://faylee.app/docs/support/widget.md), it adds `window.faylee` to it. Call `metadata` with an object:

```js
window.faylee?.metadata({
  userId: currentUser.id,
  plan: currentUser.plan,
  release: "2026.09.30",
  featureFlags: ["new-checkout"]
})
```

The `?.` matters. For people without the extension, and on pages Faylee does not capture, `window.faylee` is not there, and the optional chaining skips the call instead of throwing.

## When to call it

Call it after sign in, and again whenever the context changes, such as when someone switches account or a flag flips. Later calls add to earlier ones. When two calls set the same key, the later value wins.

Values are kept only while Faylee is capturing the page. A call made on a site Faylee is off for, or while instant replay is off and nothing is recorded, is ignored.

## Where it shows

In the viewer, the **Info** tab lists it under **App metadata**, above the browser and system details. The [assistant](https://faylee.app/docs/viewer/assistant.md) reads it when it looks into a recording, and so do coding agents connected over [MCP](https://faylee.app/docs/agents/mcp.md).

When a recording has no metadata, workspace admins see **App metadata** with an **Add** button in its place, which shows the snippet to copy.

## What to pass

Keep it to plain values: strings, numbers, booleans, and arrays and objects of them. Faylee keeps:

- Objects four levels deep.
- Up to 50 keys in an object and 100 items in an array.
- Strings up to 10,000 characters.

Anything beyond that is cut off.

## Secrets are hidden

Metadata goes through the same redaction as the rest of the capture, in the browser, before upload. Keys that look like secrets, such as `apiKey`, `sessionToken` or `password`, are replaced with `[redacted]`, and values that look like tokens are hidden wherever they appear. See [Review and share](https://faylee.app/docs/capture/review-and-share#what-is-hidden-before-upload) for the full list.

It is still best not to pass secrets at all. Pass an id you can look up, not a token.

## TypeScript

`window.faylee` is not part of the DOM types. Declare it once, in any `.d.ts` file your project includes:

```ts
// faylee.d.ts
export {}

declare global {
  interface Window {
    faylee?: {
      metadata(data: Record<string, unknown>): void
    }
  }
}
```

The property is optional, so TypeScript makes you use `?.`, which is what you want:

```ts
function tellFaylee(user: { id: string; plan: string }) {
  window.faylee?.metadata({
    userId: user.id,
    plan: user.plan,
    release: import.meta.env.VITE_RELEASE,
  })
}
```
