import { TraceItXSensitive } from '@traceitx/react-native';
<TraceItXSensitive>
<CardNumberField />
</TraceItXSensitive>
The masking happens in the producer, before capture — masked content never enters the screenshot buffer or the replay stream, let alone the upload. It is not a flag a viewer is trusted to honour.
Marking a view you do not own
When the thing to mask is rendered by a third-party component that will not accept a wrapper, take a ref instead:
import { useRef, useState } from 'react';
import type { LayoutRectangle } from 'react-native';
import { useTraceItXSensitiveRef } from '@traceitx/react-native';
function Card() {
const ref = useRef(null);
const [rect, setRect] = useState<LayoutRectangle | null>(null);
useTraceItXSensitiveRef(ref, rect);
return <ThirdPartyCardView ref={ref} onLayout={(e) => setRect(e.nativeEvent.layout)} />;
}
The hook takes your ref rather than returning one, so it composes with a ref
you already have. Its second argument is the view’s layout rect (null until
you have one); it registers on every rect change. The rect is a hint — the
native side resolves the view from its tag and reads the actual frame at
capture time, so masking follows the view across re-layouts rather than pinning
a rectangle that goes stale when the keyboard opens.
What it covers
| Screenshot | The region is painted as a solid block. |
| Session replay | Nodes carry masked: true and paint as a block. |
| Console & network | Not covered — those are text streams. Use Redaction. |
That last row is the one to remember: this is about pixels. A card number
that also appears in a fetch body needs a redaction rule as well.
Secure text inputs
<TextInput secureTextEntry> is masked automatically. Anything else that
happens to hold a secret does need marking.
Choosing what to wrap
Wrap the smallest view that contains the secret. Wrapping a whole screen makes the report useless without making it meaningfully safer, and a blanked screenshot is a common reason a report gets closed as unreproducible.