Skip to main content
@capgo/capacitor-textinteraction UI & System Open source

Text Interaction Capacitor plugin

Turn text selection and the iOS magnifier lens off in the Capacitor WebView when your app should feel native, then turn it back on before the user needs to type.

  • iOS · Supported (iOS 14.5+)
  • Android · Not supported (resolves success: false)
  • Web · Not supported (throws unimplemented)

Install

bun add @capgo/capacitor-textinteraction bunx cap sync
npm, pnpm or yarn
  • npm install @capgo/capacitor-textinteraction
  • pnpm add @capgo/capacitor-textinteraction
  • yarn add @capgo/capacitor-textinteraction

Guide

How to use Text Interaction in Capacitor

Test on device

Download the Capgo app, then scan the QR code.

Text Interaction plugin preview QR code

Disable text selection and the magnifier lens in Capacitor iOS apps

@capgo/capacitor-textinteraction gives you one call to switch text interaction on or off for the Capacitor WebView on iOS. When it is off, long-pressing text no longer selects it, shows the copy callout, or brings up the magnifier lens that iOS 15 reintroduced. Your web app stops feeling like a web page inside a native shell.

Under the hood the plugin sets WKPreferences.isTextInteractionEnabled on the app's WKWebView. It changes nothing else.

When to use it

  • Games, kiosks and drawing apps where long-press and drag gestures should never select text.
  • Custom long-press menus that clash with the native selection handles and callout.
  • Media players, maps and carousels where a slow swipe accidentally triggers the loupe.
  • Branded, app-like UI where selectable labels and buttons break the native feel.

Keep text interaction on for screens where users read long content they may want to copy, or where they fill in forms.

Install

bun add @capgo/capacitor-textinteraction
bunx cap sync

No Info.plist keys, permissions or capacitor.config.ts entries are needed.

Plugin version Capacitor version Maintained
v8.x v8.x Yes
v7.x v7.x On demand
v6.x and older v6.x and older No

Disable text interaction on app start

import { Capacitor } from '@capacitor/core';
import { TextInteraction } from '@capgo/capacitor-textinteraction';

if (Capacitor.getPlatform() === 'ios') {
  const { success } = await TextInteraction.toggle({ enabled: false });
  if (!success) console.warn('Text interaction could not be changed on this device');
}

Always pass enabled explicitly. The native side treats a missing value as false.

Re-enable it before users type

While text interaction is off, <input>, <textarea> and contenteditable elements stop accepting input. Turn it back on for any screen with a form, then turn it off again when the user leaves.

import { Capacitor } from '@capacitor/core';
import { TextInteraction } from '@capgo/capacitor-textinteraction';

const isIos = Capacitor.getPlatform() === 'ios';

export async function setTextInteraction(enabled: boolean) {
  if (!isIos) return false;
  const { success } = await TextInteraction.toggle({ enabled });
  return success;
}

// Entering a login, search or checkout screen
await setTextInteraction(true);

// Leaving it
await setTextInteraction(false);

With a router, call setTextInteraction(true) in the enter hook of routes that contain inputs (for example Vue Router beforeEnter, a React useEffect, or Angular ionViewWillEnter) and setTextInteraction(false) when leaving them.

Plugin vs CSS

You can hide most selection with CSS:

body {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

input,
textarea,
[contenteditable] {
  -webkit-user-select: text;
  user-select: text;
}

CSS works per element, so anything you forget stays selectable, and it does not change how the WebView itself handles long-press. The plugin works at the WebView level: one call covers every screen, including the magnifier lens. Many apps use both: the plugin for app-like screens and CSS for fine control inside screens where text interaction stays on.

API reference

toggle(options)

toggle(options: { enabled: boolean }): Promise<{ success: boolean }>

Turns text interaction on or off for the Capacitor WebView.

  • enabled: true restores selection, the callout and the magnifier lens. false disables them.
  • success: true when the change was applied (iOS 14.5+ with a WebView available). false on Android and when no WebView is available.

getPluginVersion()

getPluginVersion(): Promise<{ version: string }>

Returns the native plugin version. Returns web in the browser.

Platform behavior

Platform Behavior
iOS 14.5+ Sets isTextInteractionEnabled on the WKWebView. Applies to all pages until toggled again.
Android No-op. Resolves { success: false }. Use CSS if you need to limit selection.
Web toggle throws an unimplemented error. Guard calls with Capacitor.getPlatform().

Troubleshooting

  • Inputs stopped working. Text interaction is still disabled. Call toggle({ enabled: true }) before the form is shown.
  • Nothing changes on Android. Expected. The plugin only supports iOS.
  • TextInteraction.toggle is not available on web. The call ran in the browser or during development in a desktop browser. Wrap it in a platform check.
  • Selection comes back after restarting the app. Each launch creates a new WebView with text interaction enabled. Call toggle({ enabled: false }) during startup.

Ship the change without an App Store review

Toggling text interaction is JavaScript. Once the plugin is in your native build, you can change where and when it runs with a Capgo live update instead of waiting for App Store review.

Full reference

FAQ

Text Interaction plugin FAQ

How do I disable text selection in a Capacitor iOS app?

Install @capgo/capacitor-textinteraction, run bunx cap sync, then call TextInteraction.toggle({ enabled: false }). The plugin sets isTextInteractionEnabled to false on the WKWebView, which turns off text selection and the magnifier lens for the whole WebView.

Why is CSS user-select: none not enough on iOS?

user-select and -webkit-touch-callout stop most selection in page content, but the WKWebView can still show the magnifier lens and selection behavior on long-press, and every element you forget to style stays selectable. The plugin switches text interaction off at the WebView level, so one call covers every screen.

Can users still type in inputs while text interaction is disabled?

No. While text interaction is disabled, text inputs, textareas and contenteditable elements stop working. Call TextInteraction.toggle({ enabled: true }) before showing a form or search field, and disable it again when the user leaves that screen.

Does the plugin work on Android or the web?

No. Text interaction toggling is iOS only. On Android the call resolves with success set to false and changes nothing. On the web the call throws an unimplemented error, so guard it with Capacitor.getPlatform() === "ios".

Which iOS and Capacitor versions are supported?

The native API needs iOS 14.5 or later. Plugin major versions follow Capacitor: use plugin v8 with Capacitor 8 and plugin v7 with Capacitor 7.

Does the setting persist after the app restarts?

The setting lives on the WebView configuration, so it stays in effect across page navigations until you call toggle again. A fresh app launch creates a new WebView with text interaction enabled, so call toggle again at startup if you want it off by default.

How do I install the Text Interaction plugin in a Capacitor app?

Run "bun add @capgo/capacitor-textinteraction" (or "npm install @capgo/capacitor-textinteraction"), then run "bunx cap sync" so the iOS and Android projects pick up the native code. Import it from "@capgo/capacitor-textinteraction" in your app code.

Does @capgo/capacitor-textinteraction work with React, Vue and Angular?

Yes. Text Interaction is a Capacitor package, so it works with any web framework that runs inside Capacitor, including Ionic, React, Vue, Angular, Svelte and plain JavaScript.

Which Capacitor version does @capgo/capacitor-textinteraction support?

Capgo plugins follow Capacitor's major version: use the plugin major version that matches your Capacitor major version (for example plugin v8 with Capacitor 8). The compatibility table in the GitHub README lists the maintained versions.

Is @capgo/capacitor-textinteraction free and open source?

Yes. The source code is public on GitHub at https://github.com/Cap-go/capacitor-textinteraction/ and the package is free to install from npm. Bug reports and pull requests are welcome.

Can I update code that uses Text Interaction without an App Store review?

Installing or upgrading the plugin changes native code, so it needs a new store build. After that, JavaScript, HTML and CSS changes that call the plugin can ship instantly with Capgo live updates.

Ship Text Interaction changes without waiting for app review

Once the plugin is in your store build, Capgo live updates push your JavaScript, HTML and CSS changes to users in minutes.

Start with Capgo