Skip to Content
New: AI Sign Language Avatars now in beta! View Sign Language feature ->
MobilePlatformsReact Native

React Native SDK

The React Native SDK walks the React fiber tree at runtime, detects WCAG 2.2 violations, reports issues to your dashboard, and provides an optional in-app accessibility panel for end users.

Version 1.2 is the current release. Zero native module dependencies, full TypeScript support, bundled declaration files — no @types/* package required.

Requirements

RequirementMinimum Version
React Native0.70+
React18.0+
@react-navigation/native6.x (optional — enables auto-scan on focus)
iOS13+
AndroidAPI 21+

Installation

# npm npm install @welcomingweb/react-native-sdk # yarn yarn add @welcomingweb/react-native-sdk

No pod install or gradle sync is required. The SDK uses only JavaScript APIs available in React Native core.

Configuration

Call WelcomingWeb.configure() once at app startup — typically in App.tsx or index.js — before any navigation renders.

App.tsx
import { WelcomingWeb } from '@welcomingweb/react-native-sdk'; WelcomingWeb.configure({ apiKey: 'YOUR_API_KEY', appId: 'com.yourcompany.yourapp', appVersion: '1.0.0', environment: 'development', autoScan: true, debug: true, });

See the full configuration reference for every supported option.

Screen Tracking

Screen tracking is the mechanism that triggers scans. The SDK provides three complementary approaches.

withAccessibilityTracking (Higher-Order Component)

The recommended approach for most screens. Wraps your component in a tracked container that scans automatically on focus.

screens/HomeScreen.tsx
import { withAccessibilityTracking } from '@welcomingweb/react-native-sdk'; function HomeScreen({ navigation }) { return <ScrollView>{/* screen content */}</ScrollView>; } export default withAccessibilityTracking(HomeScreen, 'HomeScreen');

Behaviour: the HOC wraps your screen in a <View ref={containerRef}> with collapsable={false}. When the screen gains navigation focus (via useFocusEffect from @react-navigation), it waits for the configured scanDelay (default 600 ms) then an idle callback before scanning.

If @react-navigation/native is not installed, the SDK falls back to useEffect (mount only). Install @react-navigation/native 6.x for proper focus-based scanning.

useAccessibilityTracking (Hook)

For function components where you prefer hook composition.

screens/ProductDetailScreen.tsx
import { useAccessibilityTracking } from '@welcomingweb/react-native-sdk'; export default function ProductDetailScreen({ route }) { const a11yRef = useAccessibilityTracking('ProductDetailScreen'); return <ScrollView ref={a11yRef}>{/* screen content */}</ScrollView>; }
⚠️

When using the hook, you must pass the returned ref to the root View or ScrollView. The SDK uses this ref to access the React fiber tree for scanning.

createNavigationObserver (Fallback)

A navigation state observer for screens that don’t use the HOC or hook. Checks whether a screen is already registered before triggering a scan, so there’s no duplicate work.

App.tsx
import { createNavigationObserver } from '@welcomingweb/react-native-sdk'; <NavigationContainer onStateChange={createNavigationObserver()}> {/* navigators */} </NavigationContainer>

Manual Scanning

Trigger a scan imperatively when auto-scan isn’t enough — for example, after a state change that re-renders the screen without re-focusing it.

const result = await WelcomingWeb.scanCurrentScreen(); console.log('Score:', result.summary.accessibilityScore); for (const issue of result.issues) { console.log(issue.severity, issue.ruleId, issue.suggestion); }

ScanResult Object

FieldTypeDescription
screenNamestringName of the scanned screen.
screenRoutestringRoute path (e.g. /ProductDetail).
componentTreeHashstringHash of the component tree for deduplication.
issuesAccessibilityIssue[]Array of detected issues.
summary.totalComponentsnumberTotal nodes found in the tree.
summary.interactiveComponentsnumberNodes with onPress, buttons, inputs, switches.
summary.issuesBySeverityobject&#123; critical: N, major: N, minor: N &#125;
summary.accessibilityScorenumberScore from 0 to 100.
scanDurationMsnumberScan execution time in milliseconds.
deduplicatedbooleanTrue if the scan was skipped (same tree as last scan).

AccessibilityIssue Object

FieldTypeDescription
ruleIdstringUnique rule identifier (e.g. mobile-touch-target-size).
wcagMappingstringWCAG criterion number (e.g. 2.5.8).
wcagLevelstringA, AA, or AAA.
severitystringcritical, major, or minor.
componentTypestringReact Native component type (e.g. TouchableOpacity).
componentPathstringFull path in the tree (e.g. Home > View > Button).
evidenceobjectMeasured values that triggered the issue.
suggestionstringHuman-readable fix suggestion.
ruleDescriptionstringBrief description of the rule.

Session Lifecycle

Development Mode

  • The first scan of the day creates a new server session. The session ID is captured and reused for all subsequent scans.
  • Concurrent screen scans are serialised — a shared session-ID promise ensures all scans share the same server session with no race conditions.
  • When the app goes to background, the SDK calls /scans/complete. If the request fails, the SDK retries on the next background event.
  • When the app resumes, the hash cache and session ID are cleared. The next scan starts a fresh session.

CI/CD Mode

Covered in full on the CI/CD integration page. In summary:

  • Set autoScan: false in configuration.
  • Call WelcomingWeb.clearScreenCache() before the scan loop.
  • Navigate to each screen and call scanScreen() manually.
  • Call submitScanSession() to create a session, submit all buffered scans, and complete it.

Lifecycle Management

destroy()

Release all SDK resources. Required for test teardown and safe re-configuration.

afterEach(() => { WelcomingWeb.destroy(); });

destroy() is safe to call multiple times. After calling it, configure() must be called again before any scanning can occur.

hasScreen(name)

Returns true if the given screen name is currently registered. Used by createNavigationObserver to avoid redundant scans.

if (WelcomingWeb.hasScreen('HomeScreen')) { // Already tracked via HOC/hook — skip observer scan }

clearScreenCache(screenName?)

Clears stored component-tree hashes used for deduplication.

// Before a CI run — force every screen to scan fresh WelcomingWeb.clearScreenCache(); // After fixing one screen — re-scan only that screen WelcomingWeb.clearScreenCache('HomeScreen');

TypeScript Support

The SDK ships with a bundled index.d.ts. No @types/* package is required.

import type { ScanResult, AccessibilityIssue, WelcomingWebConfig, IssueSeverity, } from '@welcomingweb/react-native-sdk'; const result: ScanResult = await WelcomingWeb.scanCurrentScreen();

Exported types: WelcomingWebConfig, ScanResult, ScanSummary, AccessibilityIssue, IssueSeverity, SubmitSessionOptions, AccessibilityPreferences, EffectiveAccessibilitySettings, LegacyAccessibilitySettings, AccessibilityPanelProps, PanelFeatureId.

Troubleshooting

”Found 0 nodes” on scan

  • The root View may have collapsable={true} (default on Android). The HOC sets collapsable={false} automatically. If using the hook, add collapsable={false} to the root view explicitly.
  • Screen content may not have mounted yet. The default scanDelay is 600 ms — increase it via configure({ scanDelay: 1200 }) for complex screens with virtualised lists.
  • A React Native version change may have altered internal fiber property names. Enable debug: true and check for [WelcomingWeb] Could not find fiber. Keys: [...].

API returns 401 Unauthorized

Check that apiKey is correct and is passed as the X-API-Key header. If using a custom reportingEndpoint, ensure the URL includes the full base path (/api/public/v1/mobile).

Issues not showing in Dashboard

Enable debug: true and check for [WelcomingWeb:API] Response: 200. If every response shows deduplicated: true, the server-side dedup is incorrectly skipping across sessions.

AccessibilityPanel not visible

The panel uses absolute positioning with zIndex 9998–9999. Place <AccessibilityPanel /> as the last child inside your NavigationContainer, after all navigators.

Scans not triggering on navigation

The SDK uses useFocusEffect from @react-navigation/native. Without it, scans only trigger on mount. Install @react-navigation/native 6.x for focus-based scanning.

Reduce Motion toggle has no effect

The SDK does not patch Animated globally. Read effectiveSettings.reduceMotion from useAccessibilityToolkit() and skip animations in your own components.

Next Steps

Last updated on