npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-content-filtering-webview

v1.0.8

Published

React Native WebView with native content filtering support (WKContentRuleList on iOS, request interception on Android)

Readme

react-native-content-filtering-webview

A React Native WebView component with native content filtering support. Uses WKContentRuleList on iOS for efficient native filtering and request interception on Android.

Features

  • Native iOS Content Blocking: Uses WKContentRuleList (same technology as Safari Content Blockers) for efficient, native-level filtering
  • Android Request Interception: Intercepts and blocks requests at the native level
  • Domain Whitelisting: Only allow resources from specific domains
  • Domain Blacklisting: Block resources from specific domains
  • Third-Party Blocking: Block all third-party requests
  • Resource Type Filtering: Block specific resource types (scripts, images, etc.)
  • HTTPS Upgrade: Automatically upgrade HTTP requests to HTTPS
  • CSS Element Hiding: Hide elements on the page using CSS selectors
  • Rule Validation: Validate rules before compilation to catch errors early
  • Safari Content Blocker Format: Uses the standard Safari Content Blocker JSON format

Installation

npm install react-native-content-filtering-webview react-native-webview
# or
yarn add react-native-content-filtering-webview react-native-webview

iOS

cd ios && pod install

Android

No additional setup required - the module auto-links.

Quick Start

Using Presets (Simple)

The easiest way to use content filtering is with presets:

import { ContentFilteringWebView } from 'react-native-content-filtering-webview';

// Only allow content from specific domains
<ContentFilteringWebView
  source={{ uri: 'https://example.com' }}
  contentFilterPreset={{
    allowedDomains: ['example.com', 'cdn.example.com'],
  }}
/>

// Block ads and trackers
<ContentFilteringWebView
  source={{ uri: 'https://example.com' }}
  contentFilterPreset={{
    blockedDomains: ['ads.example.com', 'tracker.example.com'],
    blockThirdParty: true,
  }}
/>

// Block specific resource types
<ContentFilteringWebView
  source={{ uri: 'https://example.com' }}
  contentFilterPreset={{
    blockedResourceTypes: ['script', 'popup'],
  }}
/>

Using Custom Rules (Advanced)

For granular control, use Safari Content Blocker format rules:

<ContentFilteringWebView
  source={{ uri: 'https://example.com' }}
  contentRules={[
    // Block all third-party resources
    {
      trigger: {
        urlFilter: '.*',
        loadType: ['third-party'],
      },
      action: { type: 'block' },
    },
    // But allow specific CDN
    {
      trigger: {
        urlFilter: '^https://cdn\\.trusted\\.com/',
      },
      action: { type: 'ignore-previous-rules' },
    },
    // Hide ad elements
    {
      trigger: { urlFilter: '.*' },
      action: { type: 'css-display-none', selector: '.ad-banner, #sidebar-ad' },
    },
    // Upgrade HTTP to HTTPS
    {
      trigger: { urlFilter: '^http://' },
      action: { type: 'make-https' },
    },
  ]}
/>

API Reference

ContentFilteringWebView

Extends all standard WebViewProps from react-native-webview.

| Prop | Type | Description | |------|------|-------------| | contentRules | ContentRule[] | Custom content filtering rules | | contentFilterPreset | ContentFilterPreset | Preset configuration for common scenarios | | contentFilteringEnabled | boolean | Enable/disable filtering (default: true if rules provided) | | onContentRulesReady | () => void | Called when rules are compiled (iOS only) | | onContentRulesError | (error: Error) => void | Called when rule compilation fails | | onResourceBlocked | (url: string, resourceType?: ResourceType) => void | Called when a resource is blocked (Android only) |

ContentFilterPreset

| Property | Type | Description | |----------|------|-------------| | allowedDomains | string[] | Whitelist - only allow these domains | | blockedDomains | string[] | Blacklist - block these domains | | blockedResourceTypes | ResourceType[] | Block specific resource types | | blockThirdParty | boolean | Block all third-party resources | | upgradeToHttps | boolean | Upgrade HTTP to HTTPS |

ContentRule

Rules follow the Safari Content Blocker format.

interface ContentRule {
  trigger: ContentRuleTrigger;
  action: ContentRuleAction;
}

ContentRuleTrigger

| Property | Type | Description | |----------|------|-------------| | urlFilter | string | Required. Regex pattern to match URLs | | urlFilterIsCaseSensitive | boolean | Case-sensitive matching (default: false) | | resourceType | ResourceType[] | Match specific resource types | | loadType | LoadType[] | 'first-party' or 'third-party' | | ifDomain | string[] | Only apply on these domains | | unlessDomain | string[] | Don't apply on these domains | | ifTopUrl | string[] | Only apply if top URL matches | | unlessTopUrl | string[] | Don't apply if top URL matches |

ContentRuleAction

| Property | Type | Description | |----------|------|-------------| | type | ActionType | Required. Action to perform | | selector | string | CSS selector (for css-display-none) |

Action Types:

  • 'block' - Block the resource
  • 'block-cookies' - Block cookies but allow resource
  • 'css-display-none' - Hide matching elements (requires selector)
  • 'ignore-previous-rules' - Whitelist (override previous blocks)
  • 'make-https' - Upgrade request to HTTPS

ResourceType

type ResourceType =
  | 'document'    // Main document
  | 'image'       // Images
  | 'style-sheet' // CSS
  | 'script'      // JavaScript
  | 'font'        // Web fonts
  | 'raw'         // XHR, fetch
  | 'svg-document'// SVG files
  | 'media'       // Audio/video
  | 'popup';      // Popups

LoadType

type LoadType = 'first-party' | 'third-party';

Validation

Validate rules before passing them to the WebView to catch errors early:

import {
  validateRules,
  validatePreset,
  validateRule,
  formatValidationErrors,
} from 'react-native-content-filtering-webview';

// Validate a preset
const presetResult = validatePreset({
  allowedDomains: ['example.com'],
  blockedDomains: ['invalid domain!'], // Will fail validation
});

if (!presetResult.valid) {
  console.error(formatValidationErrors(presetResult.errors));
  // Output: preset.blockedDomains[0]: Invalid domain format (got: "invalid domain!")
}

// Validate custom rules
const rulesResult = validateRules([
  {
    trigger: { urlFilter: '(unclosed' }, // Invalid regex
    action: { type: 'block' },
  },
]);

if (!rulesResult.valid) {
  console.error(formatValidationErrors(rulesResult.errors));
  // Output: rules[0].trigger.urlFilter: URL filter contains invalid regex pattern
}

// Validate individual helpers
import { isValidDomain, isValidRegex, isValidCssSelector } from 'react-native-content-filtering-webview';

isValidDomain('example.com');        // true
isValidDomain('*.example.com');      // true (wildcard)
isValidDomain('not valid!');         // false

isValidRegex('.*');                  // true
isValidRegex('^https?://');          // true
isValidRegex('(unclosed');           // false

isValidCssSelector('.ad-banner');    // true
isValidCssSelector('#sidebar > div'); // true
isValidCssSelector('<div>');         // false

Utility Functions

import {
  presetToRules,
  rulesToJson,
  shouldBlockUrl,
  urlMatchesDomain,
  cleanupPersistedRules,
} from 'react-native-content-filtering-webview';

// Convert a preset to ContentRule array
const rules = presetToRules({
  blockedDomains: ['ads.com'],
  blockThirdParty: true,
});

// Convert rules to Safari Content Blocker JSON string
const json = rulesToJson(rules);

// Check if a URL matches a domain (includes subdomains)
urlMatchesDomain('https://sub.example.com/page', 'example.com'); // true
urlMatchesDomain('https://other.com/page', 'example.com');       // false

// Check if a URL should be blocked based on preset
shouldBlockUrl(
  'https://ads.com/banner.js',
  'https://mysite.com',
  { blockedDomains: ['ads.com'] }
); // true

// Clean up persisted rules from previous sessions (iOS only)
// Call on app startup if needed
await cleanupPersistedRules();

Platform Differences

iOS

  • Uses WKContentRuleList for native WebKit-level filtering
  • Rules are compiled once and cached
  • Extremely efficient - filtering happens in the WebKit process
  • onResourceBlocked is NOT available (WebKit limitation)
  • Rules persist across app sessions (use cleanupPersistedRules() to clear)

Android

  • Uses shouldInterceptRequest for request interception
  • Filtering happens in the native module
  • onResourceBlocked IS available
  • Rules are not persisted

Common Patterns

Whitelist Mode

Only allow specific domains:

<ContentFilteringWebView
  source={{ uri: 'https://myapp.com' }}
  contentFilterPreset={{
    allowedDomains: [
      'myapp.com',
      'api.myapp.com',
      'cdn.myapp.com',
    ],
  }}
/>

Privacy Mode

Block trackers and third-party content:

<ContentFilteringWebView
  source={{ uri: 'https://example.com' }}
  contentFilterPreset={{
    blockThirdParty: true,
    blockedDomains: [
      'google-analytics.com',
      'facebook.com',
      'doubleclick.net',
    ],
    upgradeToHttps: true,
  }}
/>

Ad Blocking with Element Hiding

<ContentFilteringWebView
  source={{ uri: 'https://example.com' }}
  contentRules={[
    // Block ad domains
    {
      trigger: { urlFilter: '^https?://([a-z0-9-]+\\.)*(ads|analytics|tracking)\\.' },
      action: { type: 'block' },
    },
    // Hide ad containers
    {
      trigger: { urlFilter: '.*' },
      action: {
        type: 'css-display-none',
        selector: '.ad, .ads, .advertisement, [class*="ad-"], [id*="ad-"]',
      },
    },
  ]}
/>

Combining Preset and Custom Rules

<ContentFilteringWebView
  source={{ uri: 'https://example.com' }}
  contentFilterPreset={{
    blockThirdParty: true,
  }}
  contentRules={[
    // Allow specific third-party CDN
    {
      trigger: { urlFilter: '^https://cdn\\.jsdelivr\\.net/' },
      action: { type: 'ignore-previous-rules' },
    },
  ]}
/>

Error Handling

<ContentFilteringWebView
  source={{ uri: 'https://example.com' }}
  contentFilterPreset={{ allowedDomains: ['example.com'] }}
  onContentRulesReady={() => {
    console.log('Content rules compiled successfully');
  }}
  onContentRulesError={(error) => {
    console.error('Failed to compile rules:', error.message);
  }}
  onResourceBlocked={(url, resourceType) => {
    console.log(`Blocked ${resourceType || 'resource'}: ${url}`);
  }}
/>

TypeScript

Full TypeScript support with exported types:

import type {
  ContentFilteringWebViewProps,
  ContentFilterPreset,
  ContentRule,
  ContentRuleAction,
  ContentRuleTrigger,
  ResourceType,
  LoadType,
  ValidationError,
  ValidationResult,
} from 'react-native-content-filtering-webview';

License

MIT