PostHog offers a range of controls to help you manage data collection. This guide covers data collection controls available to you before data reaches PostHog servers.
You should consider the following tools to help you manage data collection:
Feature | Description |
---|---|
Asking for opt out | A top-level opt out of all data collection |
Autocapture behavior | Configure what elements and interactions are automatically captured |
Masking sensitive information | Prevent specific sensitive data from being collected |
Overriding captured events | Modify or filter event data before it's sent to PostHog |
Cookieless tracking | Track users without using browser cookies |
Identifying users | Set up user identification and manage user properties |
If you require that certain data never reaches PostHog servers, you can use one of the tools below to prevent data from being captured.
Asking for opt out
Before capturing data, you may need to ask your users for consent. PostHog provides a top level switch to control data collection.
Opting out on a PostHog client will prevent all data from being captured and sent to PostHog. This includes any autocaptures, manual captures, and session replays.
Opting in and out
You can opt out the current device by calling posthog.opt_out_capturing()
.
posthog.opt_out_capturing()
Similarly, you can opt users in:
posthog.opt_in_capturing()
Checking if a user is opted out
You can check if a user is opted out by calling posthog.has_opted_out_capturing()
.
posthog.has_opted_out_capturing()
Opt out preference persistence
Opting out status is persisted automatically using:
- local storage or cookies for browsers
- shared preferences for Android
posthog.optOut
file in your app's support directory for iOS.posthog-rn.json
for React Native
For browsers, you can control how long the opt out state is persisted by setting opt_out_capturing_persistence_type
to either local_storage
or cookies
.
posthog.init('<ph_project_api_key>', {opt_out_capturing_persistence_type: 'local_storage',});
To persist opt out across sessions and devices, you can save your user's opt out preferences in your app logic. On launch, you can check if the user has opted out and set the opt out state accordingly.
Opting out by default
To opt users out by default, set opt_out_capturing_by_default
to true
in the init
call.
posthog.init('<ph_project_api_key>', {opt_out_capturing_by_default: true,});
Autocapture
PostHog has powerful autocapture features that capture data automatically on the client side. Autocapture is available for Web, iOS, and React Native, and is used by product analytics, web vitals, and heatmaps.
Project level autocapture controls
You can control autocapture behavior at the project level in Settings > Project > Autocapture & heatmaps.
Session level autocapture controls
You can also control autocapture behavior programmatically on the client side.
In web apps using the JavaScript Web SDK, the following data can be autocaptured.
Feature | Data captured |
---|---|
Product analytics | Pageviews, pageleaves, clicks, changes of inputs, and form submissions associated with <a> , <button> , <form> , <input> , <select> , <textarea> , and <label> tags |
Web analytics | Pageviews, pageleaves, conversions, and web vitals |
Session replay | Clicks, mouse movements, scrolling, and snapshots of the DOM |
Error tracking | Exceptions thrown in the browser using onError and onUnhandledRejection |
You can control autocapture using the autocapture
option in the posthog.init
call.
You can disable autocapture entirely by setting autocapture
to false
.
posthog.init('<ph_project_api_key>', {api_host: 'https://us.i.posthog.com',autocapture: false,})
You can also control what is captured using the AutocaptureConfig
object.
posthog.init('<ph_project_api_key>', {api_host: 'https://us.i.posthog.com',autocapture: {dom_event_allowlist: ['click'], // DOM events from this list ['click', 'change', 'submit']url_allowlist: ['posthog.com./docs/.*'], // strings or RegExps// url_ignorelist can be used on its own, or combined with url_allowlist to further filter which URLs are capturedurl_ignorelist: ['posthog.com./docs/.*/secret-section/.*'], // strings or RegExpselement_allowlist: ['button'], // DOM elements from this list ['a', 'button', 'form', 'input', 'select', 'textarea', 'label']css_selector_allowlist: ['[ph-autocapture]'], // List of CSS selectorselement_attribute_ignorelist:['data-attr-pii="email"'], // List of element attributes to ignore},})
Hide sensitive information with autocapture
You can also mask individual elements of the view hierarchy from being captured.
PostHog will make a best effort to not capture sensitive information by default. This is not always sufficient, so you can disable autocapture for specific elements.
By default, PostHog only collects the name
, id
, and class
attributes from <input>
tags.
If there are other HTML elements you don't want captured, you can add the ph-no-capture
class to the element.
<button class='ph-no-capture'>Sensitive information here</button>
Masking sensitive information
You can safely capture session replays events without compromising your users' privacy. PostHog offers a range of masking techniques that let you mask over sensitive information.
The following masking techniques are available:
- Masking inputs: Mask out sensitive inputs from being captured. Individual inputs can be unmasked.
- Masking text elements: Mask out sensitive text from being captured. Individual text elements can be unmasked.
- Masking other elements: Mask out any individual element from being captured.
- Redacting information on network captures: Redact sensitive information from network captures.
Private by default
If you have data that should never be captured, a safe way to start with PostHog is to mask all inputs and text, only selectively unmasking elements that you need to capture.
You can set specific data attributes on elements to control whether they are captured or not:
{// mask all inputs by defaultmaskAllInputs: true,maskTextSelector: "*",maskTextFn: (text, element) => {// only elements with `data-capture="true"` will be capturedif (element?.dataset['capture'] === 'true') {return text}return '*'.repeat(text.trim().length)},}
Selectively unmasking elements is not currently available for mobile session replay. You should be more selective about which screens you capture, and take care to mask out sensitive information.
Masking all inputs and text by default in session replay ensures that data is only captured when explicitly unmasked, putting you in control of what's captured.
Overriding captured events
Before an event is sent to PostHog, you have a final chance to modify it to remove sensitive information. You can do this by using the before_send
hook. This hook is only available for the JavaScript Web SDK.
posthog.init('<ph_project_api_key>', {api_host: 'https://us.i.posthog.com',defaults: '2025-05-24',before_send: function(event) {if (event.properties['$current_url']) {event.properties['$current_url'] = null;}return event;},})
Cookieless tracking
PostHog can be configured to do cookieless tracking by setting cookieless_mode
to always
or on_reject
.
First is cookieless_mode: "always"
:
- Doesn't require a cookie banner (unless something else on your website uses cookies)
- Never stores PostHog data in cookies or local/session storage
- Prevents you from calling
identify()
, as a distinct ID would be considered Personal Data under GDPR and other similar privacy regulations - Counts the number of users on your site using a privacy-preserving hash, calculated on PostHog's servers
Second is cookieless_mode: "on_reject"
:
- Is useful if you do want to show a cookie banner and only enable cookies when the user consents with
posthog.opt_in_capturing()
or similar method - Never stores PostHog data in cookies or local/session storage until the user opts in
- No events are captured until after consent is either given or denied
- If consent is denied, still counts those users, using a privacy-preserving hash calculated on PostHog's servers
Using cookieless_mode
helps comply with cookie and consent requirements. You still need to configure data collection and storage separately to comply with relevant regulations.
Do not send data that could be used to identify users (e.g. setting an email address as a person property if they have not given consent.
For more information on how to set up cookieless audience measurement, you can follow our detailed tutorial on cookieless tracking.
Identifying users
To track users across sessions and devices, PostHog needs to identify them. This is done by calling posthog.identify()
.
Some features depend on cohorts to work well. Some information beyond a basic distinct_id
is required to use these features:
- Feature flags - target specific user segments in experiments
- Surveys - Enable for specific cohorts of users
- Insights - filter and breakdown by user characteristics
posthog.identify('distinct_id', // Replace 'distinct_id' with your user's unique identifier{ email: 'max@hedgehogmail.com', name: 'Max Hedgehog' } // optional: set additional person properties);
Information you pass to posthog.identify()
will be sent to PostHog servers. Depending on your compliance requirements, you may not be able to store some of this information.
If you plan to use these features, consider how you can identify these groups of users without breaking compliance requirements.