# JavaScript web configuration - Docs

When calling `posthog.init`, there are various configuration options you can set to customize and control the behavior of PostHog.

## Configuration builder

Use this interactive builder to generate your `posthog.init` configuration. Select the options you need and copy the generated code.

Where is PostHog hosted?US CloudEU Cloud

Use recommended defaults

Sets defaults to the latest recommended behaviors

Enable autocapture

Automatically capture clicks, form submissions, and other interactions

Single-page app (SPA)

Detect page changes via history API instead of page loads

Enable session recording

Record user sessions for replay

Project token

Show advanced options

Generated configurationReset

posthog-init.js

PostHog AI

```javascript
posthog.init('<ph_project_token>', {
    api_host: 'https://us.i.posthog.com',
})
```

### Next steps

1.  Copy the generated code and add it to your app where PostHog is initialized.
2.  See the [full JavaScript SDK docs](/docs/libraries/js.md) for more features like identifying users, capturing custom events, and using feature flags.

You can also use the `posthog.set_config` method to change the configuration after initialization.

TypeScript

PostHog AI

```typescript
posthog.set_config({
  persistence: 'localStorage+cookie',
})
```

There are many configuration options, most of which you do not have to ever worry about. For brevity, only the most relevant ones are used here; however, you can view all options in the [`PostHogConfig` specification](/docs/references/posthog-js/types/PostHogConfig.md).

Some of the most relevant options are:

| Attribute | Description |
| --- | --- |
| api_hostType: StringDefault: https://us.i.posthog.com | URL of your PostHog instance. |
| ui_hostType: StringDefault: undefined | If using a [reverse proxy](/docs/advanced/proxy.md) for api_host then this should be the actual PostHog app URL (e.g. https://us.posthog.com). This ensures that links to PostHog point to the correct host. |
| autocaptureType: Boolean or AutocaptureConfigDefault: true | Determines if PostHog should [autocapture](/docs/product-analytics/autocapture.md) events. This setting does not affect capturing pageview events (see capture_pageview). [See below for AutocaptureConfig](#configuring-autocapture) |
| before_sendType: FunctionDefault: function () {} | A function that allows you to amend or reject events before they are sent to PostHog. [See below for more information](/docs/libraries/js/features.md#amending-or-sampling-events) |
| bootstrapType: ObjectDefault: {} | An object containing the distinctID, isIdentifiedID, and featureFlags keys, where distinctID is a string, and featureFlags is an object of key-value pairs |
| capture_pageviewType: Boolean or StringDefault: true | Determines if PostHog should automatically capture pageview events. The default is to capture using page load events. If the special string history_change is provided, PostHog will capture pageviews based on path changes by listening to the browser's history API which is useful for single page apps. history_change is the default if you choose to set defaults: '2025-05-24' or later. |
| capture_pageleaveType: BooleanDefault: true | Determines if PostHog should automatically capture pageleave events. |
| capture_dead_clicksType: BooleanDefault: true | Determines if PostHog should automatically capture dead click events. |
| cross_subdomain_cookieType: BooleanDefault: true | Determines if cookie should be set on the top level domain (example.com). If posthog-js is loaded on a subdomain (test.example.com), and cross_subdomain_cookie is set to false, it'll set the cookie on the subdomain only (test.example.com). |
| [custom_blocked_useragents](/docs/libraries/js/features.md#blocking-bad-actors)Type: ArrayDefault: [] | A list of user agents to block when sending events. |
| defaultsType: StringDefault: unset | Configuration defaults for breaking changes. When set to a specific date, enables new default behaviors that were introduced on that date. Set to '<ph_posthog_js_defaults>' to use the most recent defaults.Options: 'unset' (legacy behaviors), '2025-05-24' (capture_pageview defaults to 'history_change'), '2025-11-30' (includes 2025-05-24 changes plus session_recording.strictMinimumDuration and rageclick.content_ignorelist enabled by default), '2026-01-30' (includes 2025-11-30 changes plus external_scripts_inject_target defaults to 'head' to avoid SSR hydration errors). |
| disable_persistenceType: BooleanDefault: false | Disable persisting user data across pages. This will disable cookies, session storage and local storage. |
| disable_surveysType: BooleanDefault: false | Determines if surveys script should load which controls whether they show up for users, and whether requests for API surveys return valid data |
| disable_session_recordingType: BooleanDefault: false | Determines if users should be opted out of session recording. |
| enable_recording_console_logType: BooleanDefault: false | Determines if console logs should be recorded as part of the session recording. [More information](/docs/session-replay/manual.md#console-logs-recording). |
| enable_heatmapsType: BooleanDefault: undefined | Determines if heatmap data should be captured. |
| evaluation_contextsType: Array of StringsDefault: undefined | Evaluation context tags that constrain which feature flags are evaluated. When set, only flags with matching evaluation contexts (or no evaluation contexts) will be returned. This helps reduce unnecessary flag evaluations and improves performance. See [evaluation contexts documentation](/docs/feature-flags/evaluation-contexts.md) for more details. Available in version 1.250.0+. The legacy parameter evaluation_environments (version 1.270.0+) is also supported for backward compatibility. |
| external_scripts_inject_targetType: Enum: 'body', 'head'Default: 'body' (or 'head' when defaults: '2026-01-30' or later) | Controls where PostHog injects external dependency scripts (for session recording, surveys, etc.) in the DOM. Use 'head' to avoid SSR hydration errors when using frameworks like Next.js, TanStack Router, or other React-based SSR setups. The 'body' option maintains legacy behavior. This addresses [hydration errors](https://github.com/PostHog/posthog-js/issues/2781) that can occur when PostHog modifies the DOM before the framework completes hydration. |
| flags_api_hostType: StringDefault: null | A separate reverse proxy host for feature flag requests. If set, all feature flag evaluation requests will use this host instead of api_host. This requires setting up your own [reverse proxy](/docs/advanced/proxy.md) and creates a logical separation between feature flags and analytics, which can help prevent feature flags from being blocked by ad blockers. See [preventing feature flags from being blocked](/tutorials/flags-adblock-prevention.md) for more details. |
| loadedType: FunctionDefault: function () {} | A function to be called once the PostHog scripts have loaded successfully. |
| mask_all_textType: BooleanDefault: false | Prevent PostHog autocapture from capturing any text from your elements. |
| mask_all_element_attributesType: BooleanDefault: false | Prevent PostHog autocapture from capturing any attributes from your elements. |
| opt_out_capturing_by_defaultType: BooleanDefault: false | Determines if users should be opted out of PostHog tracking by default, requiring additional logic to opt them into capturing by calling posthog.opt_in_capturing. |
| opt_out_persistence_by_defaultType: BooleanDefault: false | Determines if users should be opted out of browser data storage by this PostHog instance by default, requiring additional logic to opt them into capturing by calling posthog.opt_in_capturing. |
| opt_out_useragent_filterType: BooleanDefault: false | Determines if users should be opted out of user agent filtering such as googlebot or other bots. By default we don't send events that match this filter. If set to true, PostHog will set $browser_type to either bot or browser instead of dropping those events. |
| persistenceType: Enum: localStorage, sessionStorage, cookie, memory, or localStorage+cookieDefault: localStorage+cookie | Determines how PostHog stores information about the user. See [persistence](/docs/libraries/js/persistence.md) for details. |
| Attribute | Description |
| --- | --- |
| property_denylistType: ArrayDefault: [] | A list of properties that should never be sent with capture calls. |
| person_profilesType: Enum: always, identified_onlyDefault: identified_only | Set whether events should capture identified events and process person profiles. |
| rate_limitingType: ObjectDefault: { events_per_second: 10, events_burst_limit: events_per_second * 10 } | Controls event rate limiting to help you avoid accidentally sending too many events. events_per_second determines how many events can be sent per second on average (default: 10). events_burst_limit sets the maximum events that can be sent at once (default: 10 times the events_per_second value). |
| logsType: ObjectDefault: undefined | Configuration options for browser logs. See [configuring logs](#configuring-logs) below. |
| session_recordingType: ObjectDefault: [See here.](https://github.com/PostHog/posthog-js/blob/96fa9339b9c553a1c69ec5db9d282f31a65a1c25/src/posthog-core.js#L1032) | Configuration options for recordings. More details [found here](/docs/session-replay/manual.md). When defaults: '2025-11-30' or later is set, strictMinimumDuration is enabled by default, which checks the minimum duration against actual buffer data rather than session duration. |
| session_idle_timeout_secondsType: IntegerDefault: 1800 | The maximum amount of time a session can be inactive before it is split into a new session. |
| xhr_headersType: ObjectDefault: {} | Any additional headers you wish to pass with the XHR requests to the PostHog API. |
| rageclickType: Boolean or RageclickConfigDefault: true | Determines if PostHog should automatically capture rage click events when users rapidly click on non-responsive elements. When defaults: '2025-11-30' or later is set, content_ignorelist is enabled by default to ignore elements with navigation-related text. [See below for RageclickConfig](#configuring-rageclick). |

## Configuring autocapture

The `autocapture` config takes an object providing full control of autocapture's behavior.

| Attribute | Description |
| --- | --- |
| url_allowlistType: Array of Strings or RegexpDefault: undefined | List of URLs to enable autocapture on, can be string or regex matches e.g. ['https://example.com', 'test.com/.*']. An empty list means no URLs are allowed for capture, undefined means all URLs are. |
| dom_event_allowlistType: Array of StringsDefault: undefined | An array of DOM events, like click, change, submit, to enable autocapture on. An empty array means no events are enable for capture, undefined means all are. |
| element_allowlistType: Array of StringsDefault: undefined | An array of DOM elements, like a, button, form, input, select, textarea, or label to allow autocapture on. An empty array means no elements are enabled for capture, undefined means all elements are enabled. |
| css_selector_allowlistType: Array of StringsDefault: undefined | An array of CSS selectors to enable autocapture on. An empty array means no CSS selectors are allowed for capture, undefined means all CSS selectors are. |
| element_attribute_ignorelistType: Array of StringsDefault: undefined | An array of element attributes that autocapture will not capture. Both an empty array and undefined mean any of the attributes from the element are captured. |
| capture_copied_textType: BooleanDefault: false | When set to true, autocapture will capture the text of any element that is cut or copied. |

## Configuring rageclick

We provide a convenient `.ph-no-rageclick` class that automatically excludes elements from rage click tracking.

But if you need more control, we also provide a `rageclick` config that takes an object providing control over rage click event detection.

| Attribute | Description |
| --- | --- |
| css_selector_ignorelistType: Array of StringsDefault: undefined | List of CSS selectors to ignore rage clicks on, e.g. ['.carousel-button', '.next-button']. Elements matching these selectors (or their parents) won't trigger rage click events. An empty array disables rage click events all together. Providing any value overrides the defaults, so PostHog will only ignore the selectors you explicitly provide in the array. |
| content_ignorelistType: Boolean or Array of StringsDefault: true when defaults: '2025-11-30' or later | Excludes elements from rage click tracking based on their text content or aria-label. When true, uses default keywords ['next', 'previous', 'prev', '>', '<']. When set to an array of strings (max 10 items), uses custom keywords. Set to false to disable content-based exclusion. Useful for preventing false positives on navigation elements. |

## Configuring logs

The `logs` config controls how browser logs are captured and sent to PostHog via OpenTelemetry.

| Attribute | Description |
| --- | --- |
| captureConsoleLogsType: BooleanDefault: undefined | When enabled, automatically captures console.log, console.warn, console.error, etc. and sends them to PostHog as structured logs. |
| serviceNameType: StringDefault: 'posthog-browser-logs' | The service name used in [OpenTelemetry resource attributes](https://opentelemetry.io/docs/specs/otel/resource/semantic_conventions/) for logs. Customize this to distinguish logs from different frontend applications or environments when viewing them in PostHog. |

Example:

JavaScript

PostHog AI

```javascript
posthog.init('<ph_project_api_key>', {
  api_host: 'https://us.i.posthog.com',
  logs: {
    serviceName: 'my-frontend-app',
  },
})
```

## Advanced configuration

These are features for advanced users and may lead to unintended side effects if not reviewed carefully.

| Attribute | Description |
| --- | --- |
| advanced_disable_flagsType: BooleanDefault: false | Will completely disable the /flags endpoint request (and features that rely on it). More details below. |
| advanced_disable_decideType: BooleanDefault: false | Legacy, prefer advanced_disable_flags. This configuration option behaves like advanced_disable_flags but will be deprecated in the future. |
| advanced_disable_feature_flagsType: BooleanDefault: false | Will keep /flags running, but without any feature flag requests. Important: do not use this argument if using surveys, as display conditions rely on feature flags internally. |
| advanced_disable_feature_flags_on_first_loadType: BooleanDefault: false | Stops from firing feature flag requests on first page load. Only requests feature flags when user identity or properties are updated, or you manually request for flags to be loaded. |
| advanced_only_evaluate_survey_feature_flagsType: BooleanDefault: false | Determines whether PostHog should only evaluate feature flags for surveys. Useful for when you want to use this library to evaluate feature flags for surveys only but you have additional feature flags that you evaluate on the server side. |
| advanced_feature_flags_dedup_per_sessionType: BooleanDefault: false | Scopes $feature_flag_called deduplication to the current session instead of per identity. Useful for [experiments](/docs/experiments.md) where a flag was evaluated before the experiment launched. Without this, returning users won't generate new [exposures](/docs/experiments/exposures.md). Mobile SDKs already deduplicate per session by default. |
| feature_flag_request_timeout_msType: IntegerDefault: 3000 | Sets timeout for fetching feature flags |
| feature_flag_cache_ttl_msType: IntegerDefault: 0 (disabled) | Sets a time-to-live for cached feature flag values. When enabled, getFeatureFlag() returns undefined instead of stale cached values if the cache is older than the TTL, and stale $feature/ properties are not attached to events. This is useful when /flags requests fail (e.g., due to ad blockers or network issues) and you want to avoid using outdated flag values indefinitely. By default (0 or undefined), cached values never expire. |
| remote_config_refresh_interval_msType: IntegerDefault: 300000 (5 minutes) | Controls how often feature flags and remote config are automatically refreshed in long-running sessions. Shorter intervals mean fresher flags but more network requests. Longer intervals reduce traffic but flag changes propagate slower. Set to 0 to disable periodic refresh entirely — flags will only update on page load or when you manually call posthog.reloadFeatureFlags(). |
| secure_cookieType: BooleanDefault: false | If this is true, PostHog cookies will be marked as secure, meaning they will only be transmitted over HTTPS. |
| custom_campaign_paramsType: ArrayDefault: [] | List of query params to be automatically captured (see [UTM Segmentation](/docs/data/utm-segmentation.md) ) |
| fetch_options.cacheType: stringDefault: undefined | fetch call cache behavior (see [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/API/RequestInit#cache) to understand available options). It's important when using NextJS, see [companion documentation](https://nextjs.org/docs/app/api-reference/functions/fetch#fetchurl-options). This is a tricky option, avoid using it unless you are aware of the changes this could cause - such as cached feature flag values, etc. |
| fetch_options.next_optionsType: ObjectDefault: undefined | Arguments to be passed to the next key when calling fetch under NextJS. See [companion documentation](https://nextjs.org/docs/app/api-reference/functions/fetch#optionsnextrevalidate). |
| on_request_errorType: FunctionDefault: logger.error('Bad HTTP status: ' + res.statusCode + ' ' + res.text) | Called whenever a PostHog request fails with an HTTP status code of 400 or higher. The callback function receives a RequestResponse object with the statusCode, text, and json (if available). |

### Disable `/flags` endpoint

> **Note:** This feature was introduced in `posthog-js` 1.10.0. Previously, disabling autocapture would inherently disable the `/flags` endpoint altogether. This meant that disabling autocapture would inadvertently turn off session recording, feature flags, compression, and the toolbar too.

One of the first things the PostHog does after initializing is make a request to [the `/flags` endpoint](/docs/api/flags.md) on PostHog's backend. This endpoint contains information on how to run the PostHog library so events are properly received in the backend and is required to run most features of the library (detailed below).

If you're not using any of these features, you may wish to turn off the call completely to avoid an extra request and reduce resource usage on both the client and the server.

The `/flags` endpoint can be disabled by setting `advanced_disable_flags` to `true`.

#### Resources dependent on `/flags`

> **Warning:** These are features/resources that are fully disabled when the `/flags` endpoint is disabled.

-   **Autocapture**. The `/flags` endpoint contains information on whether autocapture should be enabled or not (apart from local configuration).
-   **Session recording**. The endpoint contains information on where to send relevant session recording events.
-   **Compression**. The endpoint contains information on what compression methods are supported on the backend (e.g. LZ64, gzip) for event payloads.
-   **Feature flags**. The endpoint contains the feature flags enabled for the current person.
-   **Surveys**. The endpoint contains information on whether surveys should be enabled or not.
-   **Toolbar**. The endpoint contains authentication information and other toolbar capabilities information required to run it.

Any custom event captures (`posthog.capture`), `$identify`, `$set`, `$set_once` and basically any other calls not detailed above will work as expected when `/flags` is disabled.

### Community questions

Ask a question

### Was this page useful?

HelpfulCould be better