Mastering the VirtualKeyboard API for Modern Web Development

Take control of on-screen keyboard behavior in your web applications with the VirtualKeyboard API. Learn to handle keyboard geometry, implement custom layouts, and create seamless mobile experiences.

Understanding the VirtualKeyboard API

The VirtualKeyboard API is a web platform feature that gives developers granular control over how their applications respond to on-screen virtual keyboards. As mobile web usage continues to dominate, ensuring a seamless user experience when virtual keyboards appear and disappear becomes essential.

Why the VirtualKeyboard API Matters

Mobile users frequently encounter frustrating experiences when virtual keyboards disrupt page layouts, hide important content, or interfere with form interactions. Traditional browser behavior automatically resizes the viewport when keyboards appear, but this one-size-fits-all approach often fails for complex applications.

The VirtualKeyboard API addresses these challenges by providing:

  • Programmatic control over keyboard visibility
  • Geometry information for precise layout calculations
  • CSS integration through environment variables
  • Flexible policies for contenteditable elements

Three Main Components

The API consists of three interconnected parts that work together to give you comprehensive control:

  1. VirtualKeyboard Interface - JavaScript API accessed via navigator.virtualKeyboard
  2. CSS Environment Variables - Declarative keyboard geometry information accessible through the env() function
  3. virtualkeyboardpolicy Attribute - HTML control for keyboard behavior on contenteditable elements

When a virtual keyboard appears, browsers traditionally resize the viewport to make space for it. This automatic resizing can cause content to reflow unexpectedly, scroll positions to shift, and layout calculations to become unreliable. The VirtualKeyboard API, as defined by the W3C VirtualKeyboard Specification, gives you the ability to opt out of this automatic behavior and implement custom adaptation strategies that better suit your application's needs.

As noted in the Chrome for Developers guide, this API is particularly valuable for applications that require precise control over their visual layout, such as games, canvas-based editors, and complex form interfaces. For mobile-first web applications, mastering this API is essential for delivering professional-grade user experiences that compete with native mobile apps.

Core VirtualKeyboard API Capabilities

Everything you need to build keyboard-aware web applications

Keyboard Geometry Access

Retrieve exact position and dimensions of the virtual keyboard using boundingRect property. Enable precise content positioning and layout calculations.

Custom Overlay Control

Prevent automatic viewport resizing with overlaysContent. Take full control over how your layout responds to keyboard appearance.

Geometry Change Events

Listen for geometrychange events to react to keyboard show/hide events. Implement reactive layout updates that adapt instantly.

Programmatic Keyboard Control

Show or hide the keyboard on demand with show() and hide() methods. Build custom keyboard interaction patterns.

CSS Environment Variables

Access keyboard insets through CSS env() function. Create declarative layouts that adapt without JavaScript overhead.

ContentEditable Policy

Control keyboard behavior on contenteditable elements with virtualkeyboardpolicy attribute. Decouple focus from keyboard visibility.

The VirtualKeyboard Interface

The VirtualKeyboard interface is your primary gateway to controlling on-screen keyboard behavior. Accessed through navigator.virtualKeyboard, this interface provides all the properties and methods needed to build keyboard-aware web applications.

Accessing the API

Before using the VirtualKeyboard API, you should verify browser support and ensure the application is running in a secure context:

// Feature detection
if ('virtualKeyboard' in navigator) {
 // VirtualKeyboard API is available
 const virtualKeyboard = navigator.virtualKeyboard;
 
 // Configure overlay behavior
 virtualKeyboard.overlaysContent = true;
 
 // Set up event listener
 virtualKeyboard.addEventListener('geometrychange', handleKeyboardChange);
} else {
 // Implement fallback strategy for unsupported browsers
 console.warn('VirtualKeyboard API not supported');
}

Secure Context Requirement

The VirtualKeyboard API is only available in secure contexts (HTTPS). This security requirement prevents malicious scripts from exploiting keyboard geometry information for fingerprinting or other attacks. When developing locally, you may need to use localhost or configure HTTPS. The MDN Web Docs emphasize that this API requires a secure context as a fundamental security measure.

Browser Compatibility

The API has varying support across browsers. Chrome and Edge (Chromium-based) provide the most complete implementation, while Firefox and Safari have limited or no support at this time.

BrowserSupport LevelNotes
ChromeFullComplete implementation with overlaysContent
EdgeFullChromium-based, full support
FirefoxLimitedExperimental or partial support
SafariLimitedLimited or no support

Interface Properties

The VirtualKeyboard interface inherits from EventTarget and adds several key properties and methods:

  • boundingRect (DOMRect, read-only) - Returns the current keyboard geometry
  • overlaysContent (boolean) - Controls whether keyboard overlays content or triggers viewport resize
  • show() (method) - Programmatically shows the keyboard
  • hide() (method) - Programmatically hides the keyboard
  • ongeometrychange (event handler) - Fires when keyboard geometry changes

The geometrychange event fires not only when the keyboard appears or disappears but also when it resizes--such as when switching between keyboard layouts or modes. When implementing cross-browser compatibility, always include fallback mechanisms for browsers that don't support this API.

The overlaysContent Property

The overlaysContent property is a boolean that controls whether the browser automatically resizes the viewport when the virtual keyboard appears. Setting this to true tells the browser to keep the viewport size fixed and allow the keyboard to overlay your content.

How overlaysContent Works

By default, browsers resize the viewport when the virtual keyboard appears, which can cause:

  • Content to be squeezed or reflowed unexpectedly
  • Scroll position changes that disorient users
  • Layout recalculations that impact performance
  • Fixed positioning elements to jump around

When you set overlaysContent = true, you opt out of this automatic behavior and take responsibility for adapting your layout. This gives you precise control but requires implementing keyboard-aware layouts in your application.

┌─────────────────────────────────────────┐
│ Viewport (Default) │
│ ┌─────────────────────────────┐ │
│ │ Page Content │ │
│ │ │ │
│ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ │
│ │ Virtual Keyboard │ │
│ │ (Viewport shrinks) │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────────┘

┌─────────────────────────────────────────┐
│ Viewport (overlaysContent) │
│ ┌─────────────────────────────┐ │
│ │ Page Content │ │
│ │ │ │
│ │ │ │
│ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ │
│ │ Virtual Keyboard │ │
│ │ (Overlays content) │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────────┘

Implementation Example

// Opt out of automatic keyboard handling
if ('virtualKeyboard' in navigator) {
 navigator.virtualKeyboard.overlaysContent = true;
 
 // Now you can respond to keyboard geometry changes
 navigator.virtualKeyboard.addEventListener('geometrychange', handleKeyboardChange);
}

Use Cases for overlaysContent

  • Canvas-based applications that need precise control over rendering areas
  • Custom scrolling containers that shouldn't be affected by viewport changes
  • Games and interactive experiences with fixed coordinate systems
  • Dual-screen applications that need consistent behavior across screens
  • Complex layouts where automatic resizing causes visual issues

Setting this property early in your application initialization ensures consistent behavior as users interact with input elements throughout the experience. This pattern is particularly important when building responsive web applications that must work flawlessly across all device types.

Accessing keyboard geometry with boundingRect
1// Reading keyboard geometry with boundingRect2const keyboardRect = navigator.virtualKeyboard.boundingRect;3 4console.log('Keyboard position:', {5 x: keyboardRect.x, // X coordinate from left edge6 y: keyboardRect.y, // Y coordinate from top edge7 width: keyboardRect.width, // Keyboard width in pixels8 height: keyboardRect.height // Keyboard height in pixels9});10 11// Using the geometry for layout calculations12function positionInputAboveKeyboard() {13 const vk = navigator.virtualKeyboard;14 const rect = vk.boundingRect;15 16 // Calculate where the input should be positioned17 const inputBottom = window.innerHeight - rect.height - 20; // 20px padding18 19 return inputBottom;20}

The boundingRect Property

The boundingRect property returns a DOMRect representing the intersection of the virtual keyboard with the document's viewport. This read-only property provides the exact geometry of the keyboard, enabling precise layout calculations.

Understanding the DOMRect

The DOMRect object contains four key values:

PropertyDescription
xHorizontal distance from the left edge of the viewport
yVertical distance from the top edge of the viewport
widthWidth of the keyboard in pixels
heightHeight of the keyboard in pixels

Practical Applications

Use boundingRect to:

  • Position form inputs above the keyboard
  • Calculate available viewport space
  • Scroll elements into view when keyboard appears
  • Adjust fixed-position elements dynamically
  • Create layout-aware components

Important Considerations

The DOMRect values are relative to the viewport, not the document. This means scrolling the page doesn't affect the coordinates. When the keyboard is hidden, all values return to zero.

When boundingRect Returns Zero Values

When the virtual keyboard is hidden, the boundingRect property returns a DOMRect with all values set to zero (x: 0, y: 0, width: 0, height: 0). This is expected behavior and can be used to detect the keyboard state:

const rect = navigator.virtualKeyboard.boundingRect;
const isKeyboardVisible = rect.height > 0;

if (isKeyboardVisible) {
// Keyboard is visible, adapt layout
} else {
// Keyboard is hidden, normal layout
}

Understanding this behavior is crucial when building interactive web applications that must gracefully handle keyboard transitions without jarring visual disruptions.

Handling geometrychange events
1// Listening for keyboard geometry changes2if ('virtualKeyboard' in navigator) {3 // Add event listener for geometry changes4 navigator.virtualKeyboard.addEventListener('geometrychange', (event) => {5 const { x, y, width, height } = event.target.boundingRect;6 7 if (height > 0) {8 console.log('Keyboard appeared:', width, 'x', height);9 // Adapt layout for keyboard visibility10 adaptLayoutForKeyboard(height);11 } else {12 console.log('Keyboard hidden');13 // Restore normal layout14 restoreNormalLayout();15 }16 });17}18 19// Using ongeometrychange property20navigator.virtualKeyboard.ongeometrychange = (event) => {21 console.log('Geometry changed');22};

The geometrychange Event

The geometrychange event fires whenever the virtual keyboard's geometry changes. This includes:

  • Keyboard appearing (transition from hidden to visible)
  • Keyboard disappearing (transition from visible to hidden)
  • Keyboard resizing (height changes due to different keyboard modes)

Event Handling Patterns

You can add event listeners in two ways:

  1. Using addEventListener: Allows multiple handlers and proper cleanup
  2. Using ongeometrychange property: Single handler assignment

Reacting to Geometry Changes

When the event fires, the boundingRect property already contains the new geometry. Use this information to:

  • Update CSS custom properties
  • Adjust element positioning
  • Scroll content into view
  • Trigger animations
  • Save/restore scroll positions

Performance Considerations

The geometrychange event can fire frequently during keyboard transitions. Optimize your handlers by:

  • Using requestAnimationFrame for visual updates
  • Debouncing rapid changes
  • Minimizing DOM reads and writes
  • Batching layout changes together

Avoiding Layout Thrashing

When handling geometry changes, read the boundingRect property only once and cache the values for all subsequent calculations:

navigator.virtualKeyboard.addEventListener('geometrychange', () => {
// Read once and use for all calculations
const rect = navigator.virtualKeyboard.boundingRect;

// Apply all layout changes using cached values
element.style.bottom = `${rect.height}px`;
scrollToElement(element);
updateAriaAttributes(rect);
});

Reading boundingRect multiple times or interleaving reads with style writes can cause layout thrashing and impact performance, especially on lower-powered mobile devices.

Implementing efficient event handlers is essential for maintaining smooth performance in mobile-optimized web applications. The geometrychange event, when used properly, enables seamless user experiences that adapt instantly to keyboard state changes.

Programmatic keyboard control with show() and hide()
1// Programmatic keyboard control2 3// Show the keyboard (requires sticky activation and manual policy)4async function showKeyboard() {5 try {6 await navigator.virtualKeyboard.show();7 console.log('Keyboard shown successfully');8 } catch (error) {9 console.error('Failed to show keyboard:', error);10 }11}12 13// Hide the keyboard14function hideKeyboard() {15 navigator.virtualKeyboard.hide();16}17 18// Example with contenteditable element19const editor = document.getElementById('editor');20 21editor.addEventListener('dblclick', async () => {22 // Double-click to show keyboard on custom event23 await navigator.virtualKeyboard.show();24});25 26editor.addEventListener('focusout', () => {27 // Hide when losing focus28 navigator.virtualKeyboard.hide();29});

The show() and hide() Methods

The show() and hide() methods provide programmatic control over keyboard visibility. These methods allow you to decouple keyboard appearance from focus events.

Method Requirements

Both methods require:

  • Secure context (HTTPS)
  • Sticky activation (user gesture such as click or tap)
  • virtualkeyboardpolicy="manual" on the target element

When to Use These Methods

Use show() and hide() when you need:

  • Keyboard on custom gestures (double-tap, long-press)
  • Delayed keyboard appearance
  • Explicit control over keyboard state
  • Custom input workflows

Error Handling

The show() method may reject if:

  • There's no sticky activation (not called from a user gesture)
  • The focused element doesn't have virtualkeyboardpolicy="manual"
  • The platform doesn't support programmatic control

Platform-Specific Restrictions

The show() and hide() methods behave differently across platforms:

  • Chrome/Edge: Full support with proper error handling
  • Firefox: May not support programmatic control
  • iOS Safari: Not supported; keyboard shows on focus regardless

Always implement proper error handling and feature detection:

async function tryShowKeyboard(element) {
if (!('virtualKeyboard' in navigator)) {
console.warn('VirtualKeyboard API not available');
return;
}

try {
await navigator.virtualKeyboard.show();
} catch (error) {
console.log('Programmatic keyboard control not supported');
// Fallback: element.focus() will still show keyboard
element.focus();
}
}

These programmatic control methods open up possibilities for building sophisticated AI-powered chat interfaces and conversational applications where keyboard behavior needs to be carefully orchestrated as part of the user experience.

CSS Environment Variables

The VirtualKeyboard API exposes six CSS environment variables that provide keyboard geometry information directly in your stylesheets. These variables enable declarative layout adaptations without requiring JavaScript.

Available Environment Variables

VariableDescriptionFallback
keyboard-inset-topDistance from viewport top to keyboard top0px
keyboard-inset-rightDistance from viewport right to keyboard right0px
keyboard-inset-bottomDistance from viewport bottom to keyboard bottom0px
keyboard-inset-leftDistance from viewport left to keyboard left0px
keyboard-inset-widthWidth of the keyboard0px
keyboard-inset-heightHeight of the keyboard0px

Using env() Function

The environment variables work with the CSS env() function, which accepts a fallback value:

.keyboard-area {
 height: env(keyboard-inset-height, 0px);
}

The fallback value is used when the keyboard is hidden or the API is unavailable.

CSS Grid Layout Example

body {
 display: grid;
 height: 100vh;
 margin: 0;
 grid-template:
 "content" 1fr
 "input" auto
 "keyboard" env(keyboard-inset-height, 0px);
}

#messages {
 grid-area: content;
 overflow-y: auto;
}

#input {
 grid-area: input;
}

#keyboard-spacer {
 grid-area: keyboard;
}

This layout automatically adjusts to reserve space for the keyboard when it appears, creating a seamless user experience without requiring any JavaScript.

CSS media queries with keyboard insets
1/* Using keyboard insets with media queries */2 3/* When keyboard is visible */4@media (env(keyboard-inset-bottom) > 0) {5 .input-container {6 margin-bottom: calc(env(keyboard-inset-height) + 20px);7 padding: 20px;8 background: white;9 }10 11 .submit-button {12 position: fixed;13 bottom: calc(env(keyboard-inset-height) + 20px);14 }15}16 17/* Responsive adjustments based on keyboard height */18@media (env(keyboard-inset-height) >= 300px) {19 .keyboard-shortcuts {20 display: none; /* Hide shortcuts when keyboard is tall */21 }22}23 24/* Foldable device with keyboard on one screen */25@media (env(keyboard-inset-right) <= env(fold-left)) {26 .search-box {27 margin-bottom: calc(env(keyboard-inset-height) + 20px);28 }29}

Responsive Keyboard Adaptations

The environment variables work seamlessly with CSS media queries, enabling responsive layouts that adapt to keyboard state:

@media (env(keyboard-inset-bottom) > 0) {
 /* Styles when keyboard is visible */
}

This approach allows you to:

  • Show/hide elements based on keyboard state
  • Adjust spacing and padding
  • Reposition fixed elements
  • Change layout grid configurations
  • Optimize for different keyboard sizes

Combining with CSS Custom Properties

Use keyboard insets with CSS custom properties for dynamic theming and complex adaptations:

:root {
 --keyboard-offset: env(keyboard-inset-height, 0px);
 --input-padding: 20px;
}

.input-wrapper {
 padding-bottom: calc(var(--keyboard-offset) + var(--input-padding));
 transition: padding-bottom 0.2s ease;
}

/* Update custom property when keyboard changes */
@media (env(keyboard-inset-bottom) > 0) {
 :root {
 --keyboard-offset: env(keyboard-inset-height);
 --input-padding: 30px;
 }
}

Combining with Other Features

Use keyboard insets with:

  • CSS Grid for complex layout structures
  • Flexbox for component-level adaptations
  • Container queries for component-based design
  • CSS custom properties for dynamic theming

This combination creates a powerful system for building responsive, keyboard-aware interfaces that adapt seamlessly to user input methods. These techniques are essential for modern responsive web design that prioritizes mobile user experience.

The virtualkeyboardpolicy Attribute

The virtualkeyboardpolicy attribute controls how the virtual keyboard behaves on contenteditable elements. This attribute allows you to decouple focus events from keyboard visibility.

Attribute Values

ValueBehavior
"auto"Default. Keyboard appears on focus/tap
"manual"Decouples focus from keyboard. Requires programmatic control

Basic Usage

<!-- Default behavior -->
<div contenteditable virtualkeyboardpolicy="auto" id="auto-editor">
 Keyboard shows automatically on focus
</div>

<!-- Manual control -->
<div contenteditable virtualkeyboardpolicy="manual" id="manual-editor">
 Keyboard only shows when explicitly requested
</div>

Manual Control Pattern

When using "manual" policy, you need to handle keyboard visibility yourself:

const editor = document.getElementById('manual-editor');

// Show keyboard on double-click
editor.addEventListener('dblclick', () => {
 navigator.virtualKeyboard.show();
});

// Keep keyboard visible while editing
editor.addEventListener('focus', () => {
 navigator.virtualKeyboard.show();
});

// Optional: hide on specific actions
editor.addEventListener('blur', () => {
 navigator.virtualKeyboard.hide();
});

Use Cases for Manual Policy

  • Custom input workflows that require pre-processing before keyboard appears
  • Rich text editors with special input modes or tool palettes
  • Games that use contenteditable for text entry
  • Demo experiences that want to control focus and keyboard behavior

The manual policy gives you complete control over when the keyboard appears, enabling creative interaction patterns that go beyond standard form input behavior. This level of control is particularly valuable when building SEO-optimized forms and interactive content that must provide exceptional user experiences to improve engagement metrics.

Implementation Patterns

Pattern 1: Chat Application Layout

Chat applications need to keep messages visible while positioning the input field above the keyboard:

// Setup VirtualKeyboard for chat
function setupChatKeyboard() {
 if (!('virtualKeyboard' in navigator)) return;
 
 navigator.virtualKeyboard.overlaysContent = true;
 
 navigator.virtualKeyboard.addEventListener('geometrychange', () => {
 const { height } = navigator.virtualKeyboard.boundingRect;
 const messages = document.getElementById('messages');
 const inputArea = document.getElementById('input-area');
 
 if (height > 0) {
 // Keyboard is visible - adjust padding
 inputArea.style.paddingBottom = `${height + 20}px`;
 
 // Scroll to bottom of messages
 scrollToMessageBottom();
 } else {
 // Keyboard hidden - reset
 inputArea.style.paddingBottom = '20px';
 }
 });
}

Pattern 2: Form with Validation

Forms that need to keep submit buttons accessible when the keyboard appears:

function setupFormKeyboard() {
 if (!('virtualKeyboard' in navigator)) return;
 
 navigator.virtualKeyboard.overlaysContent = true;
 
 navigator.virtualKeyboard.addEventListener('geometrychange', () => {
 const { height } = navigator.virtualKeyboard.boundingRect;
 const submitBtn = document.getElementById('submit');
 
 if (height > 0) {
 // Position button above keyboard
 submitBtn.style.position = 'fixed';
 submitBtn.style.bottom = `${height + 20}px`;
 } else {
 // Reset to normal positioning
 submitBtn.style.position = 'static';
 }
 });
}

Pattern 3: Canvas-Based Application

Canvas applications can use geometry changes to redraw content:

function setupCanvasKeyboard() {
 navigator.virtualKeyboard.overlaysContent = true;
 
 navigator.virtualKeyboard.addEventListener('geometrychange', () => {
 requestAnimationFrame(() => {
 const { x, y, width, height } = navigator.virtualKeyboard.boundingRect;
 
 // Reposition active cell above keyboard
 repositionActiveCell();
 
 // Redraw canvas
 canvas.draw();
 });
 });
}

These patterns demonstrate the versatility of the VirtualKeyboard API for different application types, from communication tools to creative applications. Each pattern can be adapted and combined to create sophisticated user experiences in advanced web applications.

Best Practices for Performance

Optimize Event Handlers

The geometrychange event can fire rapidly during keyboard transitions. Follow these performance guidelines:

Do:

// Batch layout changes
navigator.virtualKeyboard.addEventListener('geometrychange', () => {
 requestAnimationFrame(() => {
 // Read geometry once
 const { height } = navigator.virtualKeyboard.boundingRect;
 
 // Apply all changes
 applyLayoutChanges(height);
 });
});

Avoid:

// Reading inside animation frame repeatedly
navigator.virtualKeyboard.addEventListener('geometrychange', () => {
 requestAnimationFrame(() => {
 // Reading multiple times causes layout thrashing
 const h1 = navigator.virtualKeyboard.boundingRect.height;
 const h2 = navigator.virtualKeyboard.boundingRect.height;
 const h3 = navigator.virtualKeyboard.boundingRect.height;
 });
});

Feature Detection and Fallbacks

Always detect support and provide fallbacks:

function setupKeyboardHandling() {
 if ('virtualKeyboard' in navigator) {
 // Use VirtualKeyboard API
 navigator.virtualKeyboard.overlaysContent = true;
 setupAdvancedKeyboardHandling();
 } else {
 // Use traditional focus-based approach
 setupFallbackKeyboardHandling();
 }
}

Accessibility Considerations

  • Maintain visible focus indicators when customizing keyboard behavior
  • Ensure interactive elements remain keyboard accessible
  • Test with screen readers and assistive technologies
  • Provide visual feedback for keyboard state changes
  • Don't break standard keyboard navigation patterns

Implementing proper accessibility ensures that all users can effectively interact with your application, regardless of their input method or assistive technology requirements. These performance and accessibility best practices are fundamental to delivering high-quality web applications that serve all users effectively.

Troubleshooting Common Issues

Issue: API Not Available

Problem: navigator.virtualKeyboard is undefined

Solutions:

  • Verify the page is served over HTTPS
  • Check browser support (Chrome/Edge only)
  • Ensure not in an iframe (unless same-origin)

Issue: Keyboard Geometry Returns Zeros

Problem: boundingRect returns all zeros

Solutions:

  • Keyboard may be hidden (this is expected behavior)
  • Check if overlaysContent is set to true
  • Verify the keyboard actually appeared on screen

Issue: show() Method Fails

Problem: show() throws an error or does nothing

Solutions:

  • Requires sticky activation (user gesture)
  • Element must have virtualkeyboardpolicy="manual"
  • Check browser console for error messages
  • Verify platform supports programmatic control

Issue: Layout Not Updating

Problem: Layout doesn't change when keyboard appears

Solutions:

  • Verify overlaysContent is set before adding event listeners
  • Check that event handlers are actually firing
  • Ensure CSS changes are being applied (check computed styles)
  • Test on actual mobile device, not desktop emulation

Debugging Tips

// Add comprehensive logging
if ('virtualKeyboard' in navigator) {
 console.log('VirtualKeyboard API available');
 
 navigator.virtualKeyboard.addEventListener('geometrychange', (event) => {
 console.log('Geometry changed');
 console.log('boundingRect:', event.target.boundingRect);
 console.log('overlaysContent:', navigator.virtualKeyboard.overlaysContent);
 });
 
 console.log('Initial overlaysContent:', navigator.virtualKeyboard.overlaysContent);
}

Using detailed logging during development helps identify issues early and ensures your keyboard handling logic is working as expected. When troubleshooting complex keyboard interactions, systematic debugging approaches help isolate problems quickly and lead to more robust implementations.

Frequently Asked Questions

Build Better Mobile Web Experiences

The VirtualKeyboard API is just one of the modern web platform features we use to create exceptional mobile experiences. Our team specializes in implementing cutting-edge web APIs that improve user engagement and satisfaction.