--- url: /start/overview.md --- # Headerly overview Headerly is a browser extension for creating reusable network rules. A rule can modify request or response headers, redirect or block a request, allow traffic, or upgrade an insecure URL scheme. Each rule is stored as a **profile** with three main parts: * an [action](/reference/actions/) that defines what the browser does; * [conditions](/reference/conditions/) that select requests; * a [priority](/reference/priorities) used when profiles overlap. Headerly uses Chrome's Declarative Net Request API. The browser evaluates and applies registered rules; Headerly manages the profile editor, storage, rule registration, and error reporting. ## Common uses * Add an authorization or feature-flag header during development. * Select an existing browser cookie and append it to matching requests. * Change response headers while testing CORS or iframe behavior. * Redirect an API or asset to another environment. * Block an unwanted request while debugging a page. * Limit a rule to one domain, method, resource type, tab, or tab group. * Export profiles for backup or sharing. ## What Headerly does not do Headerly does not provide a network log, inspect request or response bodies, modify bodies, or act as a system proxy. Browser and DNR restrictions still apply to every profile. Continue with [installation](/start/installation), or create [your first profile](/start/first-profile). --- --- url: /start/installation.md --- # Install Headerly Install Headerly from one of the supported extension stores: * [Chrome Web Store](https://chromewebstore.google.com/detail/headerly/lmlapacaojgifapgjkbdkmaclkgcbhng) * [Microsoft Edge Add-ons](https://microsoftedge.microsoft.com/addons/detail/headerly/dhkjobinnldebfgpondcjlefklcapnha) Headerly requires Chrome 145 or a compatible Chromium-based browser version. After installation, pin Headerly to the browser toolbar if you want one-click access. Open the extension to display the Profiles page. ## Keyboard shortcut Open `chrome://extensions/shortcuts`, find Headerly, and assign a shortcut to **Turn Headerly on or off**. Use it to quickly pause or resume every Headerly rule without opening the extension. ## Permissions The core extension uses the following permissions: | Permission | Purpose | | --- | --- | | `storage` | Stores profiles, settings, registration records, and errors | | `declarativeNetRequest` | Registers browser network rules | | Host access to `` | Allows rules and cookie lookup across configured sites | Cookie synchronization and tab-group conditions request additional permissions only when used. ### `cookies` Requested when cookie synchronization is added or imported. It allows Headerly to list selected-domain cookies, read their values, and receive change notifications. Headerly does not create or delete browser cookies through this feature. ### `tabGroups` Requested when a Tab Groups condition is added. It allows Headerly to list groups and observe group removal. Headerly uses the Tabs API to resolve the tabs contained in each group. Declining an optional permission cancels the operation that requires it. Existing unrelated profiles continue to work. --- --- url: /start/first-profile.md --- # Create your first profile In this tutorial, we will add a request header to requests sent to the current website. ## Before you start * Install Headerly. * Open a normal HTTP or HTTPS page. * Open the Headerly popup from the browser toolbar. ## Create the rule 1. Create a `modifyHeaders` profile. 2. Name it `Headerly demo`. 3. Keep the generated **Request domains** condition. Confirm that it contains the current site's hostname. 4. In **Modify request header**, enter: * Name: `X-Headerly-Demo` * Value: `enabled` * Operation: `Set` by default. 5. Keep the profile enabled. Headerly registers the profile automatically. The active-rule popup badge should change to `1`. ## Check the result 1. Open the browser's Developer Tools. 2. Select the **Network** panel. 3. Reload the page. 4. Select a request sent to the configured hostname. 5. Inspect its request headers. You should see: ```http X-Headerly-Demo: enabled ``` If the header is absent, follow [Rule not applied](/troubleshooting/rule-not-applied). ## Remove the change Pause the profile. Reload the page and confirm that the header is no longer present. You have created, verified, and paused a complete Headerly profile. Next, see the guides for [request headers](/guides/modify-request-headers) and [conditions](/reference/conditions/). --- --- url: /guides/modify-request-headers.md --- # Modify request headers Use a request-header rule to change headers before the browser sends a matching request. 1. Create or select a `modifyHeaders` profile. 2. Add **Modify request header** if the profile does not already contain it. 3. Enter the header name. 4. Choose an operation: * `set` to create or replace the value; * `append` to add a value to an allowed request header; * `remove` to delete the header. 5. Enter a non-empty value for `set` or `append`. 6. Add conditions that limit the affected requests. 7. Reload the target page and inspect the request in Developer Tools. ::: warning Append is restricted Chrome permits `append` only for a fixed, case-sensitive list of request-header names. Use `set` when the header is not on that list. See [Modify headers reference](/reference/actions/modify-headers#append-restrictions). ::: When profiles modify the same header, set explicit [priorities](/reference/priorities) and verify the final request. --- --- url: /guides/modify-response-headers.md --- # Modify response headers Use a response-header rule to change headers after a matching response reaches the browser. 1. Create or select a `modifyHeaders` profile. 2. Add **Modify response header**. 3. Enter the response-header name. 4. Choose `set`, `append`, or `remove`. 5. Enter a value for `set` or `append`. 6. Restrict the profile with request conditions. 7. Reload the target resource. Common development uses include changing CORS, Content Security Policy, cache, or framing headers. Changing a response header does not change the response body or the origin server's configuration. ::: warning Security controls Removing security headers weakens browser protections for matching traffic. Keep the conditions narrow and pause the profile when testing is complete. ::: ## Verify the modified header ::: warning Do not rely on the Network panel Because of [Chromium issue 40196848](https://issues.chromium.org/issues/40196848), the Network panel can show the server's original response headers instead of changes made by `declarativeNetRequest`. A missing or unchanged header in that panel does not prove that the Headerly rule failed. ::: Open Developer Tools on the target origin and run a same-origin request in the Console: ```js const response = await fetch("/api/endpoint", { cache: "no-store" }); Object.fromEntries(response.headers.entries()); ``` Replace `/api/endpoint` with a URL matched by the profile, then inspect the returned object for the modified header. See [Modify headers reference](/reference/actions/modify-headers) for operation and priority behavior. --- --- url: /guides/sync-cookies.md --- # Synchronize a cookie into requests Use cookie synchronization when a request header must follow the current value of a browser cookie. Cookie sync is a convenience wrapper around a **Modify request header** action using the `append` operation: Headerly supplies the current local cookie value instead of requiring a fixed header value. ::: warning Sensitive access This feature requests the optional `cookies` permission. Cookie values can contain sessions and credentials. Keep the target conditions narrow so the copied value is appended only to intended requests. ::: 1. Select a `modifyHeaders` profile. 2. Add **Cookie sync to request header**. 3. Grant the Cookies permission when prompted. (Your browser may grant it automatically; if no permission prompt appears, skip this step.) 4. Enter the source domain or paste a URL from that domain. Make sure the resulting Domain exactly matches the **Domain** column in Developer Tools > **Application** > **Cookies**. Preserve any leading dot: if DevTools shows `.example.com`, do not enter `example.com` without the dot. 5. Select the exact cookie, including its domain and path. 6. Add conditions that identify only the requests that should receive it. 7. Send a target request and inspect its `Cookie` request header. Headerly appends the selected cookie as `name=value`. When the source cookie changes, Headerly updates the stored value. A missing, deleted, expired, or empty cookie is not appended. ## Reuse the profile on another computer For security, Headerly does not include synchronized Cookie values in exported JSON, downloaded profiles, or share links. It exports the Cookie identity—Domain, Path, and Name—with an empty Value. After another user imports the profile and grants Cookie access, Headerly uses that identity to find the matching Cookie in their browser and synchronizes their local value. This lets multiple users reuse the same profile configuration without transferring Cookie credentials. The matching Cookie must already exist locally, and its Domain, Path, and Name must match exactly. Use a normal request-header modification when the value should remain fixed. See [Synchronize cookies reference](/reference/actions/sync-cookies) for identity and partitioning limitations. --- --- url: /guides/redirect-requests.md --- # 🚧 Redirect requests ::: warning Work in progress Redirect support is under development. Headerly currently supports only the simplest case: redirecting one complete URL to another complete URL. Future versions will support **regex substitution** and URL transformations for replacing individual components such as the path, host, or query. ::: Use a Redirect profile to send matching requests to one fixed URL. 1. Create a `redirect` profile. 2. Enter an absolute HTTP or HTTPS destination in **Simple redirect URL**. 3. Add conditions that identify the source requests. 4. Enable the profile and load a matching URL. 5. Confirm the final URL and requested resource in Developer Tools. The destination is used as written. ::: warning Redirect loops Ensure the destination does not also match the source conditions unless another condition breaks the cycle. ::: See [Redirect reference](/reference/actions/redirect). --- --- url: /guides/block-or-allow-requests.md --- # Block or allow requests ## Block matching requests 1. Create a `block` profile. 2. Add conditions for the requests to stop. 3. Enable the profile and reproduce the request. 4. Confirm in Developer Tools that the request was blocked. ## Exempt traffic from other profiles Create an `allow` profile when matching traffic should bypass lower-priority blocking, redirect, upgrade, or header-modification rules from Headerly. 1. Create an `allow` profile. 2. Add narrow conditions for the exception. 3. Give it a priority at least as high as the rules it must override. 4. Verify the request and all expected headers. Use `allowAllRequests` only when you need an exception for a complete frame hierarchy. See [Allow](/reference/actions/allow), [Allow all requests](/reference/actions/allow-all-requests), and [priority behavior](/explanation/priority-and-conflicts). --- --- url: /guides/apply-profile-to-tabs.md --- # Apply a profile to tabs or tab groups Use tab conditions when a profile should affect selected browser tabs instead of every matching tab. ## Current tab 1. Open the target tab. 2. Add **Tab IDs** to the profile. 3. Select or add the current tab. 4. Verify the rule in that tab and in a second tab. Use **Excluded tab IDs** to apply a rule everywhere except selected tabs. ## Tab group 1. Put the target tabs in a Chrome tab group. 2. Add **Tab groups** to the profile. 3. Grant the optional Tab Groups permission. 4. Select the group. 5. Add or remove a tab from the browser group and verify that Headerly updates the rule. ::: warning Browser restart clears selections Selections saved under **Tab IDs** and **Tab groups** are cleared when the browser restarts. Chrome only guarantees tab and tab-group IDs within the current browser session, so this is a browser limitation, not a Headerly limitation. Headerly automatically pauses any profile that had an active tab or tab-group condition before the restart. This prevents the profile from unexpectedly applying to more tabs after its saved selection is cleared. Select the tabs or groups again before resuming the profile. ::: See [Tab IDs](/reference/conditions/tabs) and [Tab groups](/reference/conditions/tab-groups). --- --- url: /guides/import-export-share.md --- # Import, export, and share profiles ## Export profiles 1. Open the Export page from a profile's **Share** action. 2. Select the profiles to include. 3. Copy the JSON, download it, or create a Headerly share link. 4. Review the exported values before sending them to anyone. Internal IDs, profile-group membership, tab IDs, and tab-group conditions are removed from exported profiles. ::: danger Review secrets Synchronized Cookie values are cleared automatically. Header values, comments, and redirect URLs are not redacted and can still contain private information. ::: ## Import profiles 1. Open the Import page. 2. Paste JSON, choose an exported file, or open a Headerly share link. 3. Review validation errors and the profiles to be added. 4. Confirm the import. Imported profiles receive new internal IDs and do not overwrite profiles with similar names. Imports containing synchronized cookies can request the optional Cookies permission. --- --- url: /reference/profiles.md --- # Profiles A profile is Headerly's top-level rule definition. An enabled, valid profile maps to one Chrome DNR rule. ## Concept map The diagram shows how Profile Groups, Profiles, Actions, Conditions, Priority, and item-group modes work together. ![Headerly concept map: an optional Profile Group contains Profiles; each Profile has one Action, optional Conditions, and a Priority; radio and checkbox modes control Profiles or items; requests pass through condition matching and priority before the Action is applied.](/images/profile-concepts.webp) ## Fields | Field | Required | Description | | --- | --- | --- | | Name | Yes | User-visible profile name | | Emoji | Yes | User-visible profile icon | | Enabled | Yes | Whether Headerly should register the rule | | Rule action type | Yes | One of the six supported [actions](/reference/actions/) | | Priority | No | Integer from 1 to 2,147,483,647; defaults to 1 | | Comments | No | Notes stored with the profile | | Profile group | No | Membership in one top-level profile group | | Actions | Depends on type | Header modifications, synchronized cookies, or redirect destination | | Conditions | No | Request-selection criteria; none means global matching | ## Lifecycle Headerly creates, updates, or removes the associated DNR rule when rule-relevant profile data changes. Pausing a profile removes its rule. Resuming it registers the current configuration. ## Valid actions `block`, `allow`, `upgradeScheme`, and `allowAllRequests` require no additional action fields. `modifyHeaders` requires at least one valid header modification or synchronized cookie. `redirect` requires one enabled, non-empty destination. Invalid rules are retained as profiles and display a registration error. See [Registration errors](/troubleshooting/registration-errors). ## Profile operations Profiles can be paused, resumed, duplicated, deleted or reset, commented, assigned a priority, moved into a group, exported, and changed to another action type. Changing action type removes action data incompatible with the new type. In the Sidebar, **Shift+Click** or middle-click a profile emoji to quickly toggle that profile's enabled state without opening it first. --- --- url: /reference/profile-groups.md --- # Profile groups Profile groups organize top-level profiles and optionally coordinate which profiles are enabled. ## Fields | Field | Description | | --- | --- | | Name | User-visible group name | | Color | Sidebar color selected from Headerly presets | | Type | `checkbox` or `radio` | | Remembered profiles | Internal list used by Pause and remember | ## Checkbox groups Any number of profiles in a checkbox group can be enabled. Enabling or disabling one profile does not automatically change the others. ## Radio groups At most one profile in a radio group can be enabled. Enabling a profile disables other enabled profiles in the same group. ## Pause and resume **Pause and remember** disables the group and records which profiles were enabled. **Resume saved profiles** restores every remembered profile in a checkbox group or the first remembered profile in a radio group. Changing a member profile's enabled state separately clears the remembered state. ## Sidebar context menus Right-click a profile emoji in the Sidebar to open its context menu. From there, you can pause or resume the profile, duplicate it, change its group membership, edit comments or priority, change its action type, export it, or delete or reset it. Right-click a profile group header to open the group context menu. From there, you can edit the group's name and color, switch between radio and checkbox mode, create a profile in the group, pause or resume remembered profiles, remove all profiles from the group, or delete the group. ## Storage and export Groups and memberships are stored locally as organizational data. They do not affect DNR rule contents. Removing the final member causes an empty group to be cleaned up. ::: warning Export support is not yet implemented Profile group definitions and profile-to-group memberships are not currently included in profile exports. Support for exporting and restoring this data remains to be implemented. ::: --- --- url: /reference/priorities.md --- # Priorities Priority is a positive integer used by Chrome to resolve matching DNR rules. | Property | Value | | --- | --- | | Minimum | 1 | | Maximum | 2,147,483,647 | | Default | 1 | Higher values are evaluated before lower values. Do not rely on ordering between rules that have the same action and priority; browser vendors do not standardize that order. Within Headerly, equal-priority actions are ordered by Chrome as follows: 1. `allow` and `allowAllRequests` 2. `block` 3. `upgradeScheme` 4. `redirect` Matching header modifications are processed separately, from higher to lower priority, after allow rules are considered. See [Priority and conflicts](/explanation/priority-and-conflicts). ## Override a header for a nested path To set a header to `a` for resources under `/path/a/`, but set the same header to `b` under `/path/a/b/`, create two overlapping Modify Headers profiles: | Profile | Header operation | URL Filter | Priority | | --- | --- | --- | --- | | `/path/a/` | Set `X-Example-Header` to `a` | `*/path/a/*` | `1` | | `/path/a/b/` | Set `X-Example-Header` to `b` | `*/path/a/b/*` | `2` | A request under `/path/a/file.js` matches only the first profile and receives `X-Example-Header: a`. A request under `/path/a/b/file.js` matches both profiles. Headerly applies the higher-priority `set` operation first, setting `X-Example-Header: b`; the lower-priority `set` operation cannot overwrite it, so the final value is `b`. The same pattern works with Regex Filter conditions. Headerly does not provide excluded URL Filter or excluded Regex Filter conditions, so overlapping profiles with different priorities are currently the only way to override a broad URL-pattern header value for a narrower URL pattern. Set an explicit priority when profiles overlap or modify the same header. --- --- url: /reference/group-modes.md --- # Radio and checkbox groups Headerly uses the same two selection modes for action items, condition items, and profile groups. ## Checkbox Multiple items can be enabled simultaneously. Use Checkbox when values should be combined, such as several request domains or header modifications. ## Radio Only one item can be enabled. Adding or enabling one item disables the others. Use Radio for mutually exclusive alternatives, such as one active configuration value. ## Effect on generated rules The group type is an editor and storage behavior. The generated DNR rule contains only the enabled values; it does not contain the words `radio` or `checkbox`. Disabled items remain available in the profile but do not affect matching or actions. --- --- url: /reference/actions.md --- # Actions An action defines what Chrome does when every enabled condition in a profile matches. | Action type | Result | Additional configuration | | --- | --- | --- | | [`modifyHeaders`](/reference/actions/modify-headers) | Modifies request or response headers | At least one valid header modification or synchronized cookie | | [`redirect`](/reference/actions/redirect) | Redirects the request | One enabled, non-empty destination URL | | [`block`](/reference/actions/block) | Blocks the request | None | | [`allow`](/reference/actions/allow) | Exempts the request from lower-priority Headerly rules | None | | [`upgradeScheme`](/reference/actions/upgrade-scheme) | Upgrades an insecure URL scheme | None | | [`allowAllRequests`](/reference/actions/allow-all-requests) | Allows a complete frame hierarchy | A frame resource type | Changing a profile's action type removes configuration that is incompatible with the new type. Conditions and priority remain unless changed separately. `block`, `allow`, `upgradeScheme`, and `allowAllRequests` are complete actions by themselves. `modifyHeaders` and `redirect` are registered only after their required configuration is valid. --- --- url: /reference/actions/modify-headers.md --- # Modify headers `modifyHeaders` changes request headers before they are sent or response headers after they are received. ## Header modification fields | Field | Required | Behavior | | --- | --- | --- | | Name | Yes | Trimmed header name. Empty names are ignored. | | Operation | Yes | `set`, `append`, or `remove` | | Value | For `set` and `append` | Trimmed value. An empty value makes the item inactive. | Disabled items remain in the profile but do not generate DNR modifications. ## Operations ### `set` Creates the header or replaces its value. Lower-priority modifications may be restricted after a `set` operation. ### `append` Adds another value. Chrome chooses the appropriate separator where possible. ### `remove` Removes the header. It does not use a value. Lower-priority rules cannot modify that header afterward. ## Request and response timing Request-header modifications run before Chrome sends headers to the server. Response-header modifications run after response headers arrive. A response modification cannot undo data already sent in the request. Chrome DevTools may not display DNR response-header changes in the Network panel because of [Chromium issue 40196848](https://issues.chromium.org/issues/40196848). This is a display limitation, not evidence that the modification failed. See [Verify a modified response header](/guides/modify-response-headers#verify-the-modified-header). ## Append restrictions Chrome only permits `append` for these request headers, using the exact lowercase spelling shown: `accept`, `accept-encoding`, `accept-language`, `access-control-request-headers`, `cache-control`, `connection`, `content-language`, `cookie`, `forwarded`, `if-match`, `if-none-match`, `keep-alive`, `range`, `te`, `trailer`, `transfer-encoding`, `upgrade`, `user-agent`, `via`, `want-digest`, `x-forwarded-for`. This allowlist is browser-defined and case-sensitive. See Chromium's [`kDNRRequestHeaderAppendAllowList`](https://chromium.googlesource.com/chromium/src/+/HEAD/extensions/browser/api/declarative_net_request/constants.h#314) for the current list and the delimiter used by each header. Response-header append is not limited by this request-header list. ## Conflicts Matching `modifyHeaders` profiles are evaluated from higher to lower priority. An earlier operation limits later operations on the same header: * after `append`, later rules may only append; * after `set`, only lower-priority rules from the same extension may append; * after `remove`, no later rule may modify the header. Matching `allow` or `allowAllRequests` rules can suppress lower-priority header modifications. See [Priority and conflicts](/explanation/priority-and-conflicts). ## Source See Chrome's [Declarative Net Request header modification](https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest#header-modification). --- --- url: /reference/actions/sync-cookies.md --- # Synchronize cookies Cookie synchronization is a Headerly action component available to `modifyHeaders` profiles. It reads a selected browser cookie and appends `name=value` to the outgoing `Cookie` header. ## Fields | Field | Purpose | | --- | --- | | Domain | Exact domain recorded for the selected cookie, including any leading dot | | Path | Exact cookie path | | Name | Cookie name | | Value | Current value copied from the browser cookie store | ## Domain and host-only scope Chrome exposes both a `domain` string and a `hostOnly` boolean for each cookie. Chromium's cookie representation encodes the same host-only distinction in the `domain` string: | Domain value | Chrome property | Scope | | --- | --- | --- | | `example.com` | `hostOnly: true` | Matches only the exact `example.com` host | | `.example.com` | `hostOnly: false` | Domain cookie that can match `example.com` and its subdomains | The leading dot does not represent a separate `hostname` property. It is Chromium's domain-string representation of the cookie's `hostOnly` scope. Headerly stores the exact `domain` value returned by Chrome instead of storing `hostOnly` separately. For this reason, the Domain value must exactly match the **Domain** column in Developer Tools > **Application** > **Cookies**. If that column contains `.example.com`, the dot is part of Headerly's cookie identity and must not be omitted. ## Cookie identity Headerly uses `domain + path + name` as the composite identity of a synchronized cookie. All three fields are required because cookies with the same name can coexist under different domains or paths. The exact domain string also distinguishes a host-only cookie from a domain cookie, so these identities are different: ```text example.com + / + session .example.com + / + session ``` Headerly uses this composite identity when reading the current value and processing cookie-change events. If the domain, leading dot, path, or name differs, Headerly treats it as another cookie. When no exact match exists, the synchronized value becomes empty and no Cookie header modification is generated. Empty names, paths, domains, or values do not produce a header modification. Multiple profile items may intentionally use the same composite identity; they will follow the same browser cookie. ## Synchronization Headerly reads configured cookie values when the extension starts, when cookie permission is granted, and when cookie identities change. It also listens for cookie changes. Deleting or expiring a cookie clears the stored value. Chrome can report an overwrite as a removal followed by an insertion; Headerly retains the latest observed change. ## Export and import Headerly clears synchronized Cookie values when generating exported JSON, downloaded profiles, and share links. Domain, Path, and Name remain in the export as the Cookie identity. After import, Headerly uses that identity to read the matching Cookie from the current user's browser. Different users can therefore use the same exported profile while Headerly synchronizes a different local value for each user. If no exact local match exists, Value remains empty and no Cookie header modification is generated. ## Permission This feature requires the optional `cookies` permission and host access for the cookie's domain. See [Permissions](/start/installation#permissions). ## Limitations The Chrome Cookies API can distinguish cookie stores and partitioned cookies with `storeId` and `partitionKey`. Headerly does not store those fields. Therefore the identity is not sufficient to distinguish every **[Cookies Having Independent Partitioned State (CHIPS, also known as )](https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Third-party_cookies/Partitioned_cookies)**, or regular-versus-incognito case. Headerly explicitly appends the selected value to matching requests. Restrict the profile conditions carefully; the source cookie's Domain, Path, SameSite, and Secure attributes do not define the target requests selected by the Headerly profile. ## Sources * [Chrome Cookies API](https://developer.chrome.com/docs/extensions/reference/api/cookies) --- --- url: /reference/actions/redirect.md --- # Redirect `redirect` sends a matching request to one fixed destination URL. ## Destination Headerly uses the first enabled, non-empty redirect item. Leading and trailing whitespace is removed. An empty destination prevents the profile from registering. Use an absolute HTTP or HTTPS URL. JavaScript URLs are not accepted by Chrome. ## Supported form Headerly exposes only the DNR `redirect.url` form. It does not expose: * `extensionPath`; * `regexSubstitution`; * URL `transform` or `queryTransform`. Capture groups in a `regexFilter` therefore cannot be inserted into the destination. ## Interactions Redirect participates in DNR priority resolution. A matching higher-priority `allow`, `allowAllRequests`, or `block` profile can prevent it from running. A destination that also matches the source condition can create a loop. See Chrome's [Redirect type](https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest#type-Redirect). --- --- url: /reference/actions/block.md --- # Block `block` stops a matching network request. ::: danger Add conditions before enabling A Block profile with no conditions applies to requests from every browser page. Enabling it can prevent all pages from opening. ::: The action has no additional fields. A profile with this action is registerable as soon as the profile is enabled, even if it has no conditions. Headerly displays a warning for global profiles. Within Headerly, an `allow` or `allowAllRequests` rule of equal or higher priority takes precedence over Block. Across extensions, Chrome gives Block higher action precedence than Redirect, Upgrade Scheme, Allow, or Allow All Requests. Use narrow [conditions](/reference/conditions/) and verify the result in Developer Tools. --- --- url: /reference/actions/allow.md --- # Allow `allow` exempts an individual matching request from lower-priority Headerly rules. The action has no additional fields. When an Allow profile matches, Headerly rules with lower priority do not block, redirect, upgrade, or modify headers for that request. Allow does not create a network request that another browser policy, server, or extension has blocked. Rule ordering between separate extensions follows Chrome's cross-extension conflict rules. Use [Allow all requests](/reference/actions/allow-all-requests) when the exception must cover a complete frame hierarchy. --- --- url: /reference/actions/upgrade-scheme.md --- # Upgrade scheme `upgradeScheme` replaces an insecure request scheme with its secure equivalent before the request is sent. Chrome upgrades HTTP to HTTPS and FTP to HTTPS. The host, path, query, and fragment remain otherwise unchanged. The destination server must support the secure URL. The action has no additional fields. Conditions determine which requests are eligible. Higher-priority Allow, Allow All Requests, or Block profiles can prevent the upgrade. --- --- url: /reference/actions/allow-all-requests.md --- # Allow all requests `allowAllRequests` allows the matching frame request and future requests in that frame hierarchy. It is broader than [`allow`](/reference/actions/allow), which applies to one request. ## Resource types Chrome requires `allowAllRequests` rules to use only: * `main_frame` * `sub_frame` Headerly does not add resource types automatically for this action. If you add a Resource Types or Excluded Resource Types condition, select only these values. ## Priority Once a frame matches, an Allow All Requests rule can suppress lower-priority Headerly actions for requests in that frame. Use a narrow URL or domain condition and an intentional priority. The action has no additional fields. --- --- url: /reference/conditions.md --- # Conditions Conditions select the network requests to which a profile applies. Different condition types are combined with logical AND. Multiple enabled values within a condition usually broaden that condition; excluded variants remove matches. | Condition | Field | | --- | --- | | [Request domains](/reference/conditions/request-domains) | `requestDomains`, `excludedRequestDomains` | | [URL filter](/reference/conditions/url-filter) | `urlFilter` | | [Regular expression filter](/reference/conditions/regex-filter) | `regexFilter` | | [URL case sensitivity](/reference/conditions/url-case-sensitivity) | `isUrlFilterCaseSensitive` | | [Initiator domains](/reference/conditions/initiator-domains) | `initiatorDomains`, `excludedInitiatorDomains` | | [Top-level domains](/reference/conditions/top-level-domains) | `topDomains`, `excludedTopDomains` | | [Domain type](/reference/conditions/domain-type) | `domainType` | | [Resource types](/reference/conditions/resource-types) | `resourceTypes`, `excludedResourceTypes` | | [Request methods](/reference/conditions/request-methods) | `requestMethods`, `excludedRequestMethods` | | [Tabs](/reference/conditions/tabs) | `tabIds`, `excludedTabIds` | | [Tab groups](/reference/conditions/tab-groups) | `tabGroups`, `excludedTabGroups` | Disabled or empty items do not contribute to a generated rule. If no conditions remain, the profile is global. Headerly always excludes its own extension ID from initiator-domain matching to avoid applying rules to itself. --- --- url: /reference/conditions/request-domains.md --- # Request domains Request-domain conditions compare against the domain of the requested URL. ::: tip Start here Request domains are usually the condition that best matches the intended scope. Prefer them when matching the destination website; they are simpler than URL and regular-expression filters, support multiple enabled values, and match subdomains automatically. ::: ## `requestDomains` The rule matches only requests whose destination domain is in the enabled list. ## `excludedRequestDomains` The rule does not match requests whose destination domain is in the enabled list. Exclusions take precedence over included request domains. Entries contain domain names only, not schemes, ports, paths, or query strings. Headerly extracts the hostname when a URL is pasted. Subdomains of an entry also match. Values must be ASCII; use Punycode for internationalized names. Example: `example.com` also matches `api.example.com`. Use [Initiator domains](/reference/conditions/initiator-domains) to match the site that started a request, rather than its destination. --- --- url: /reference/conditions/url-filter.md --- # URL filter `urlFilter` matches the complete network-request URL using Chrome's compact filter syntax. ::: warning Prefer Request domains when possible Use [Request domains](/reference/conditions/request-domains) unless it cannot express the match you need. Request domains are simpler, more predictable, and support multiple enabled values in checkbox mode. `urlFilter` is limited to one enabled value because of the underlying API; complex filters are harder to troubleshoot. ::: ## Tokens | Token | Meaning | | --- | --- | | `*` | Any number of characters | | `\|` | Start or end of the URL when placed at the corresponding edge | | `\|\|` | Start of a domain or subdomain when placed first | | `^` | A separator character or the end of the URL | Examples: ```text ||example.com/ |https://api.example.com/ example.com/path ``` Use `||example.com/` instead of `example.com` when the intent is to match a domain. An unanchored value can also match text in a path or query string. The filter must be non-empty ASCII. Internationalized hosts are matched in Punycode form and other non-ASCII URL characters are percent-encoded. Only one of `urlFilter` and `regexFilter` can be generated. The UI prevents both from being configured; if imported data contains both, an enabled non-empty Regex Filter takes precedence. `urlFilter` itself also supports only one enabled value, not checkbox-style multiple selection. ## Troubleshooting Consult Chrome's [URL filter syntax](https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest#url-filter-syntax) for the complete grammar. Headerly passes the configured filter to Chrome's DNR API after trimming leading and trailing whitespace. If a filter does not match as expected, check that syntax and Chrome's matching behavior; Headerly does not reinterpret the value. --- --- url: /reference/conditions/regex-filter.md --- # Regular expression filter `regexFilter` matches the complete network-request URL with Chrome's RE2 regular-expression engine. ::: warning Prefer Request domains when possible Use [Request domains](/reference/conditions/request-domains) unless it cannot express the match you need. Request domains are simpler, more predictable, and support multiple enabled values in checkbox mode. `regexFilter` is limited to one enabled value because of the underlying API; complex expressions are harder to troubleshoot. ::: Enter the expression directly, without JavaScript-style `/.../` delimiters: ```text ^https://api\.example\.com/v[0-9]+/ ``` ## Syntax limits RE2 deliberately omits constructs that require backtracking. In particular, it does not support: * backreferences such as `\1`; * positive or negative lookahead; * positive or negative lookbehind. Ordinary capturing and non-capturing groups are supported, but Headerly's fixed Redirect action cannot substitute their captured values. The expression must contain only ASCII. Chrome matches it against a URL with Punycode hostnames and percent-encoded non-ASCII characters. ## Browser limits * Each DNR ruleset type can contain at most 1,000 regular-expression rules. * A compiled expression must use less than 2 KB. * Unsupported syntax or excessive compiled memory causes rule registration to fail. Chrome exposes `isRegexSupported()` for validation. Headerly currently relies on DNR registration and displays the returned registration error. Only one of `regexFilter` and `urlFilter` can be used. `regexFilter` itself also supports only one enabled value, not checkbox-style multiple selection. See [URL case sensitivity](/reference/conditions/url-case-sensitivity). ## Troubleshooting Consult [Chrome's DNR `regexFilter` reference](https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest#type-RuleCondition) and [RE2 syntax](https://github.com/google/re2/wiki/syntax) for the complete grammar. Headerly passes the configured expression to Chrome's DNR API after trimming leading and trailing whitespace. If an expression does not match as expected, check those sources and Chrome's matching behavior; Headerly does not reinterpret the value. --- --- url: /reference/conditions/url-case-sensitivity.md --- # URL case sensitivity `isUrlFilterCaseSensitive` controls case sensitivity for whichever URL matcher is active: `urlFilter` or `regexFilter`. | Value | Behavior | | --- | --- | | `false` | Match without case sensitivity | | `true` | Match with case sensitivity | The condition has its own enabled state. When disabled or absent, Headerly omits the field and Chrome uses its default value, `false`. This setting does not change domain normalization, Punycode conversion, or URL percent encoding. --- --- url: /reference/conditions/initiator-domains.md --- # Initiator domains Initiator-domain conditions compare against the origin that initiated a request, not the requested URL. ## `initiatorDomains` The rule matches only requests initiated by a listed domain. ## `excludedInitiatorDomains` The rule excludes requests initiated by a listed domain. Exclusions take precedence over included initiator domains. Subdomains match. Entries must be ASCII domain names; use Punycode for internationalized names. Headerly always adds its own extension ID to `excludedInitiatorDomains`. This internal exclusion prevents profiles from affecting Headerly's extension pages and requests. Requests do not always have a conventional website initiator. Test Service Worker and extension-generated requests separately when initiator matching matters. --- --- url: /reference/conditions/top-level-domains.md --- # Top-level domains Top-level-domain conditions compare against the domain of the associated top-level frame. ## `topDomains` The rule matches only when the top-level frame belongs to a listed domain. ## `excludedTopDomains` The rule excludes requests associated with a listed top-level domain. Exclusions take precedence over included top-level domains. Subdomains match. Values must be ASCII domain names; use Punycode for internationalized names. For a request without an associated top-level frame, such as some Service Worker requests, Chrome uses the initiator domain instead. These fields require Chrome 145, which is also Headerly's current minimum Chrome version. Use this condition when the same third-party resource should be modified only while it is used by a particular top-level site. --- --- url: /reference/conditions/domain-type.md --- # Domain type `domainType` selects whether a request is first-party or third-party relative to the domain from which it originated. | Value | Meaning | | --- | --- | | `firstParty` | The request is first-party to its originating domain | | `thirdParty` | The request is third-party to its originating domain | When the condition is disabled or absent, both types can match. Domain Type is a relationship test. It is not a substitute for explicit [Request domains](/reference/conditions/request-domains), [Initiator domains](/reference/conditions/initiator-domains), or [Top-level domains](/reference/conditions/top-level-domains). --- --- url: /reference/conditions/resource-types.md --- # Resource types Resource-type conditions select requests by their browser resource category. ## Fields * `resourceTypes` includes the selected types. * `excludedResourceTypes` excludes the selected types. Use one field or the other. Enabled items are combined and duplicate values are removed. ## Values `main_frame`, `sub_frame`, `stylesheet`, `script`, `image`, `font`, `object`, `xmlhttprequest`, `ping`, `csp_report`, `media`, `websocket`, `webtransport`, `webbundle`, `other`. `xmlhttprequest` includes requests Chrome classifies as XMLHttpRequest or Fetch traffic. Classification is performed by the browser. ## Headerly default For every rule except `allowAllRequests`, when neither field contains a value, Headerly explicitly adds every resource type to the registered rule. This keeps rules broadly usable: Chrome's default DNR behavior applies to only a small subset of resource types, which can make a rule appear not to apply. Headerly does not offer a setting for Chrome's native default behavior. To narrow a rule's scope, add a Resource Types or Excluded Resource Types condition and select one or more values. `allowAllRequests` does not receive a default resource-type list. See [Allow all requests](/reference/actions/allow-all-requests). --- --- url: /reference/conditions/request-methods.md --- # Request methods Request-method conditions select requests by HTTP method. ## Fields * `requestMethods` includes the selected methods. * `excludedRequestMethods` excludes the selected methods. Use one field or the other. Enabled items are combined and duplicate values are removed. ## Values `connect`, `delete`, `get`, `head`, `options`, `patch`, `post`, `put`, `other`. Values are displayed as uppercase HTTP method names in the UI and stored in lowercase. Specifying `requestMethods` also excludes non-HTTP(S) requests. Specifying only `excludedRequestMethods` does not have that additional effect. --- --- url: /reference/conditions/tabs.md --- # Tab IDs Tab ID conditions bind a profile to browser tabs. ## `tabIds` The rule matches only requests associated with the selected tabs. ## `excludedTabIds` The rule excludes requests associated with the selected tabs. ## Lifetime Closing a selected tab removes it from the condition. If no selected tabs remain, Headerly disables the profile. ::: warning Browser restart clears selections Selections saved under **Tab IDs** and **Tab groups** are cleared when the browser restarts. Chrome only guarantees these IDs within the current browser session, so this is a browser limitation, not a Headerly limitation. Headerly automatically pauses any profile that had an active tab or tab-group condition before the restart. This prevents the profile from unexpectedly applying to more tabs after its saved selection is cleared. ::: Use [Tab groups](/reference/conditions/tab-groups) when membership should follow a browser tab group. --- --- url: /reference/conditions/tab-groups.md --- # Tab groups Tab-group conditions are a synchronized form of [Tab ID conditions](/reference/conditions/tabs). Instead of selecting individual tabs, select a Chrome tab group. Headerly applies the profile to the tabs currently in that group and keeps the effective tab selection synchronized with the browser group. ## `tabGroups` The rule includes tabs in the selected groups. ## `excludedTabGroups` The rule excludes tabs in the selected groups. When tabs are added to, removed from, or moved between selected groups, Headerly automatically updates which tabs the profile applies to. ## Lifetime Removing a selected group removes it from the condition. If no selected tabs remain, Headerly disables the profile. ::: warning Browser restart clears selections Selections saved under **Tab IDs** and **Tab groups** are cleared when the browser restarts. Chrome only guarantees these IDs within the current browser session, so this is a browser limitation, not a Headerly limitation. Headerly automatically pauses any profile that had an active tab or tab-group condition before the restart. This prevents the profile from unexpectedly applying to more tabs after its saved selection is cleared. ::: ## Permission Selecting a group requires the optional `tabGroups` permission. See the [Chrome Tab Groups API](https://developer.chrome.com/docs/extensions/reference/api/tabGroups). --- --- url: /explanation/declarative-net-request.md --- # How Headerly uses Declarative Net Request Headerly does not proxy network traffic. It translates each enabled profile into a declarative rule and asks Chrome to register that rule. A DNR rule contains an integer ID, priority, action, and condition. Headerly owns the mapping between its UUID-based profile IDs and Chrome's integer rule IDs. When a rule-relevant profile field changes, the background worker computes the changed profiles and updates only their registered rules. Chrome evaluates those rules inside the browser network stack. This design lets the browser apply actions without sending request or response bodies to Headerly's JavaScript code. ## Rule lifecycle 1. Headerly stores the profile locally. 2. Enabled, registerable profiles are converted into DNR actions and conditions. 3. Headerly registers or updates the corresponding browser rules. 4. Registration IDs and errors are stored for the popup. 5. The toolbar badge reflects active registered rules. Pausing a profile removes its rule. Turning off Headerly removes all Headerly rules. Reinitialization removes and rebuilds them from the saved profiles. See [Profiles](/reference/profiles) and Chrome's [Declarative Net Request API](https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest). --- --- url: /explanation/how-conditions-combine.md --- # How conditions combine Conditions describe one request from several perspectives: its URL and destination, the origin that initiated it, the top-level page around it, its method and resource type, and the tab where it occurs. Different condition types narrow one another. For example, a profile can require a destination domain, a `GET` method, and an `xmlhttprequest` resource type. Exclusions remove matches from their corresponding include set. ## Included and excluded values Included values narrow the requests that can match. Excluded values remove requests from that result. When a profile has several condition types, a request must satisfy all of them. ## Tabs and tab groups Tab and Tab Group conditions apply the same profile to selected tabs or exclude those tabs from otherwise matching requests. Selections saved under **Tab IDs** and **Tab groups** are cleared when the browser restarts. Chrome only guarantees these IDs within the current browser session, so this is a browser limitation, not a Headerly limitation. Headerly automatically pauses any profile that had an active tab or tab-group condition before the restart. This prevents the profile from unexpectedly applying to more tabs after its saved selection is cleared. --- --- url: /explanation/priority-and-conflicts.md --- # Priority and conflicts Several profiles can match the same request. Chrome resolves them in stages, not as one flat list. ## Before the request For Headerly rules, Chrome first compares priority. At the same priority, action precedence is: 1. Allow and Allow All Requests 2. Block 3. Upgrade Scheme 4. Redirect An Allow action prevents lower-priority Headerly actions from affecting that request. Allow All Requests can extend that exemption through a frame hierarchy. When multiple extensions compete, Chrome uses a different action ordering and installation recency can decide ties. Headerly cannot guarantee the outcome of another extension's rules. ## Header modification Header changes occur later. Matching Modify Headers rules above any applicable Allow priority are processed from higher to lower priority. Earlier operations constrain later changes to the same header: * Append permits only later appends. * Set permits only later appends from the same extension. * Remove permits no later modification. ## Practical model Assign higher priorities to narrow exceptions and lower priorities to broad defaults. Avoid equal priority when order matters. Verify the final request because browser policy and other extensions remain outside Headerly's control. See [Priorities](/reference/priorities) and Chrome's [rule evaluation](https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest#rule-evaluation). --- --- url: /explanation/privacy-model.md --- # Privacy model Headerly relies on declarative browser rules. The browser applies matching actions internally; Headerly does not proxy traffic or read request and response bodies. Profiles, settings, rule registrations, and registration errors are stored in the extension's local storage. They are not automatically uploaded by Headerly. ## Host access Headerly has host access for all URLs so user-created profiles can target arbitrary sites. Conditions in a profile determine the requests affected by that profile. ## Cookie synchronization Cookie synchronization is different from ordinary DNR configuration. After the optional Cookies permission is granted, Headerly reads selected cookie values and watches them for changes. Those values are stored in profiles and can be appended to matching requests. Treat synchronized values as secrets. A profile's target conditions, not the original cookie attributes, control where the copied value is appended. ## Export and sharing Headerly clears synchronized Cookie values before generating exported JSON, downloaded profiles, or share links. It retains the Cookie identity so an imported profile can synchronize against the receiving user's local Cookie. Other user-configured values remain in exports. Share links compress and encode the export but do not encrypt it. Review headers, comments, and URLs before exporting or sharing a profile. --- --- url: /troubleshooting/rule-not-applied.md --- # Rule not applied Check the profile from top to bottom. 1. Confirm that Headerly is turned on. 2. Confirm that the profile and the required group item are enabled. 3. Confirm that the action is registerable: * `modifyHeaders` needs a non-empty header name and, except for `remove`, a non-empty value; * `redirect` needs an enabled, non-empty destination; * synchronized cookies need a valid identity and non-empty current value. 4. Check every enabled condition. Different condition types must all match. 5. For URL matching, test the complete request URL rather than the page URL. 6. Check the request's Resource Type and Request Method in Developer Tools. 7. For Tab or Tab Group conditions, select the tab or group again and resume the profile if the selected tab or group was closed or the browser restarted. 8. Check the profile for a registration error. 9. Check whether a higher-priority Allow or Allow All Requests profile suppresses the action. 10. Pause other network-modifying extensions and retry. If the profile is valid but its rule state appears stale, open Settings and run **Reinitialize all rules**. This rebuilds rules without deleting profiles. --- --- url: /troubleshooting/unexpected-matches.md --- # Unexpected matches ## URL Filter is too broad An unanchored value can match in the path or query. Prefer `||example.com/` for a domain and `|https://example.com/` for one exact scheme and host. ## Domain matches subdomains Request, initiator, and top-level domain entries also match subdomains. Use URL Filter or Regex Filter when the boundary must be narrower. ## The wrong domain perspective is used * Request Domains examine the destination URL. * Initiator Domains examine what started the request. * Top-level Domains examine the surrounding top-level page. Choose the perspective that represents the intended restriction. ## No Resource Type is configured Except for `allowAllRequests`, Headerly explicitly matches all resource types by default. Add a Resource Types or Excluded Resource Types condition and select one or more values to narrow the rule. Headerly does not provide a setting for Chrome's native resource-type default. `allowAllRequests` does not receive an automatic resource-type list. See [Resource types](/reference/conditions/resource-types) for its restrictions. ## A global profile is enabled A profile with no effective conditions can affect every request supported by DNR. Add at least one narrow condition unless global behavior is intentional. --- --- url: /troubleshooting/registration-errors.md --- # Registration errors Headerly stores DNR registration errors against the profile that produced them. The profile remains editable but does not have a working registered rule until the error is corrected. Common causes include: * unsupported or overly complex RE2 syntax; * `append` applied to a request header outside Chrome's allowlist; * an invalid redirect URL; * an action with no valid required data; * incompatible include and exclude conditions; * a condition value unsupported by the current browser; * Chrome rule or regular-expression quotas. Correct the highlighted profile and let Headerly register it again. If the error remains after the profile is valid, run **Reinitialize all rules** in Settings. Reinitialization removes and rebuilds Headerly rules. It does not change Chrome's API limits and cannot resolve conflicts caused by another extension. For Regex errors, remove JavaScript `/.../` delimiters and unsupported look-around or backreference syntax. See [Regular expression filter](/reference/conditions/regex-filter). --- --- url: /share.md --- # Open shared profiles Headerly share links are handled by the browser extension. Install Headerly if it is not already available in this browser: * [Download for Chrome](https://chromewebstore.google.com/detail/headerly/lmlapacaojgifapgjkbdkmaclkgcbhng) * [Download for Microsoft Edge](https://microsoftedge.microsoft.com/addons/detail/headerly/dhkjobinnldebfgpondcjlefklcapnha) If the Import page does not open: 1. Install and enable Headerly. 2. Open the complete share link in the same browser profile. 3. Confirm that no characters were removed from the URL. Shared payloads are compressed and encoded, not encrypted. Synchronized Cookie values are cleared before sharing, but ordinary header values and other profile data remain. Review imported profiles and their target conditions before enabling them.