or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-operations.mdindex.mdreact-integration.mdscheme-management.mdurl-operations.md
tile.json

scheme-management.mddocs/

Scheme Management

Advanced scheme resolution and validation for Expo and React Native applications, handling development vs production environments and app configuration.

Capabilities

Check Custom Scheme Usage

Determines if the app uses a custom URL scheme based on the execution environment.

/**
 * Check if app uses custom URL scheme based on execution environment
 * - Bare workflow: always uses custom scheme
 * - Standalone: uses custom scheme when defined in manifest
 * - Store client (Expo Go): uses default scheme
 * @returns true if app uses custom scheme, false otherwise
 */
function hasCustomScheme(): boolean;

Usage Example:

import { hasCustomScheme } from "expo-linking";

if (hasCustomScheme()) {
  console.log("App uses custom scheme - deep links will use app-specific protocol");
} else {
  console.log("App uses default scheme - likely running in Expo Go");
}

Collect Manifest Schemes

Retrieves platform-specific schemes from the Expo configuration manifest.

/**
 * Collect a list of platform schemes from the manifest.
 * Based on the Scheme modules from @expo/config-plugins used for collecting schemes before prebuilding.
 * Resolution order:
 * - Android: scheme -> android.scheme -> android.package
 * - iOS: scheme -> ios.scheme -> ios.bundleIdentifier
 * @returns Array of scheme strings defined in the app configuration
 */
function collectManifestSchemes(): string[];

Usage Example:

import { collectManifestSchemes } from "expo-linking";

const schemes = collectManifestSchemes();
console.log("Available schemes:", schemes);
// Example output: ["myapp", "myapp-dev", "com.company.myapp"]

// Check if specific scheme is available
const hasDevScheme = schemes.includes("myapp-dev");
if (hasDevScheme) {
  console.log("Development scheme is configured");
}

Check Constants Manifest

Verifies that the expo-constants manifest is properly linked in bare workflow.

/**
 * Ensure the user has linked the expo-constants manifest in bare workflow.
 * Required for scheme resolution and deep linking functionality.
 * @returns true if constants manifest is available, false otherwise
 */
function hasConstantsManifest(): boolean;

Usage Example:

import { hasConstantsManifest } from "expo-linking";

if (!hasConstantsManifest()) {
  console.warn("expo-constants manifest not found - deep linking may not work properly");
  console.warn("Follow setup instructions: https://github.com/expo/expo/blob/main/packages/expo-constants/README.md");
}

Resolve Scheme

Resolves the appropriate scheme for deep linking with validation and environment handling.

/**
 * Resolve appropriate scheme for deep linking, handles validation and warnings.
 * Throws errors in production if no scheme is configured.
 * @param options - Configuration options for scheme resolution
 * @returns The resolved scheme string
 * @throws Error if no scheme is configured in production builds
 */
function resolveScheme(options: ResolveSchemeOptions): string;

interface ResolveSchemeOptions {
  /** Preferred scheme to use - will be validated against app config */
  scheme?: string;
  /** Whether to suppress validation warnings in development */
  isSilent?: boolean;
}

Usage Examples:

import { resolveScheme } from "expo-linking";

// Use default scheme from app config
const defaultScheme = resolveScheme({});
console.log("Default scheme:", defaultScheme);

// Use specific scheme with validation
const customScheme = resolveScheme({ 
  scheme: "myapp-production" 
});
console.log("Custom scheme:", customScheme);

// Silent resolution (no warnings)
const silentScheme = resolveScheme({ 
  scheme: "myapp-dev",
  isSilent: true 
});

Environment-Specific Behavior:

  • Expo Go (Store Client): Returns 'exp' or provided scheme if it's a valid Expo client scheme
  • Development: Validates provided scheme against app config, shows warnings for mismatches
  • Production: Throws error if no scheme is configured, uses first available scheme from manifest

Advanced Scheme Management

Dynamic Scheme Selection

import { 
  resolveScheme, 
  collectManifestSchemes, 
  hasCustomScheme 
} from "expo-linking";

function getOptimalScheme(environment: 'dev' | 'staging' | 'prod'): string {
  const availableSchemes = collectManifestSchemes();
  
  // Select scheme based on environment
  const envSchemeMap = {
    dev: `myapp-dev`,
    staging: `myapp-staging`, 
    prod: `myapp`
  };
  
  const preferredScheme = envSchemeMap[environment];
  
  if (availableSchemes.includes(preferredScheme)) {
    return resolveScheme({ scheme: preferredScheme });
  }
  
  // Fallback to default
  return resolveScheme({});
}

Scheme Validation Helper

import { 
  collectManifestSchemes, 
  hasCustomScheme,
  hasConstantsManifest 
} from "expo-linking";

interface SchemeValidationResult {
  isValid: boolean;
  hasCustomScheme: boolean;
  availableSchemes: string[];
  warnings: string[];
  errors: string[];
}

function validateSchemeSetup(): SchemeValidationResult {
  const warnings: string[] = [];
  const errors: string[] = [];
  
  // Check if constants manifest is available
  if (!hasConstantsManifest()) {
    errors.push("expo-constants manifest not found");
  }
  
  const schemes = collectManifestSchemes();
  const customScheme = hasCustomScheme();
  
  if (!customScheme && schemes.length === 0) {
    warnings.push("No custom scheme configured - app may not handle deep links properly in production");
  }
  
  if (schemes.length > 1) {
    warnings.push(`Multiple schemes found: ${schemes.join(', ')} - first scheme will be used by default`);
  }
  
  return {
    isValid: errors.length === 0,
    hasCustomScheme: customScheme,
    availableSchemes: schemes,
    warnings,
    errors
  };
}

// Usage
const validation = validateSchemeSetup();
if (!validation.isValid) {
  console.error("Scheme setup errors:", validation.errors);
}
if (validation.warnings.length > 0) {
  console.warn("Scheme setup warnings:", validation.warnings);
}

Configuration Examples

App Config Setup

{
  "expo": {
    "scheme": "myapp",
    "ios": {
      "bundleIdentifier": "com.company.myapp",
      "scheme": "myapp-ios"
    },
    "android": {
      "package": "com.company.myapp",
      "scheme": "myapp-android"
    }
  }
}

Multiple Environment Schemes

{
  "expo": {
    "scheme": ["myapp", "myapp-dev", "myapp-staging"]
  }
}