> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flinks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Mobile & Native App Integration

> Integrate Flinks Connect into iOS, Android, and React Native apps using WebView.

Flinks Connect can be embedded in native mobile applications using a WebView. This guide covers setup for iOS (WKWebView), Android (WebView), and React Native.

## WebView parameter

Add `webview=true` to your Flinks Connect iframe URL when loading it inside a native WebView. This changes the event communication method — instead of using `window.postMessage`, Flinks Connect emits events to `window.ReactNativeWebView.postMessage` (React Native) or the native WebView message handler.

```url theme={null}
https://[instance]-iframe.private.fin.ag/v2/?webview=true&demo=true&redirectUrl=https://example.com/callback
```

## iOS (WKWebView)

### Setup

```swift theme={null}
import WebKit

class FlinksViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler {

    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let config = WKWebViewConfiguration()
        let preferences = WKPreferences()
        preferences.javaScriptCanOpenWindowsAutomatically = true
        config.preferences = preferences

        // Listen for Flinks Connect events
        config.userContentController.add(self, name: "flinksEvent")

        webView = WKWebView(frame: view.bounds, configuration: config)
        webView.navigationDelegate = self
        view.addSubview(webView)

        let url = URL(string: "https://[instance]-iframe.private.fin.ag/v2/?webview=true&demo=true&redirectUrl=https://example.com/callback")!
        webView.load(URLRequest(url: url))
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "flinksEvent", let body = message.body as? String {
            print("Flinks event: \(body)")
            // Parse the JSON event and handle accordingly
        }
    }
}
```

<Warning>
  You must set `javaScriptCanOpenWindowsAutomatically = true` on iOS. OAuth-based institutions open a popup for authentication, and WebViews block popups by default.
</Warning>

## Android (WebView)

### Setup

```kotlin theme={null}
import android.webkit.WebView
import android.webkit.WebViewClient
import android.webkit.WebChromeClient
import android.webkit.WebSettings

class FlinksActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val webView = WebView(this)
        setContentView(webView)

        val settings: WebSettings = webView.settings
        settings.javaScriptEnabled = true
        settings.javaScriptCanOpenWindowsAutomatically = true
        settings.domStorageEnabled = true

        webView.webViewClient = WebViewClient()
        webView.webChromeClient = WebChromeClient()

        webView.loadUrl("https://[instance]-iframe.private.fin.ag/v2/?webview=true&demo=true&redirectUrl=https://example.com/callback")
    }
}
```

<Warning>
  Both `javaScriptEnabled = true` and `javaScriptCanOpenWindowsAutomatically = true` are required on Android. Without these, Flinks Connect will not function correctly.
</Warning>

## React Native

### Using `react-native-webview`

```jsx theme={null}
import React, { useRef } from 'react';
import { WebView } from 'react-native-webview';

const FlinksConnect = ({ onSuccess, onError }) => {
  const webViewRef = useRef(null);

  const handleMessage = (event) => {
    try {
      const data = JSON.parse(event.nativeEvent.data);
      console.log('Flinks event:', data);

      switch (data.step) {
        case 'COMPONENT_LOAD_INSTITUTION':
          // Widget loaded — institution selector is visible
          break;
        case 'REDIRECT':
          // User has successfully connected — extract loginId
          if (data.loginId) {
            onSuccess(data.loginId, data.institution);
          }
          break;
        case 'COMPONENT_LOAD_CREDENTIAL':
          // User selected an institution
          break;
        case 'INSTITUTION_SELECTED':
          // Institution chosen
          break;
        default:
          break;
      }
    } catch (e) {
      console.error('Failed to parse Flinks event:', e);
    }
  };

  return (
    <WebView
      ref={webViewRef}
      source={{
        uri: 'https://[instance]-iframe.private.fin.ag/v2/?webview=true&demo=true&redirectUrl=https://example.com/callback',
      }}
      javaScriptEnabled={true}
      javaScriptCanOpenWindowsAutomatically={true}
      domStorageEnabled={true}
      onMessage={handleMessage}
      style={{ flex: 1 }}
    />
  );
};

export default FlinksConnect;
```

## Event sequence (happy path)

When a user successfully connects their account, Flinks Connect emits the following events in order:

| Order | Event                        | Description                                 |
| :---- | :--------------------------- | :------------------------------------------ |
| 1     | `COMPONENT_LOAD_INSTITUTION` | Widget loaded, institution selector visible |
| 2     | `INSTITUTION_SELECTED`       | User selected a financial institution       |
| 3     | `COMPONENT_LOAD_CREDENTIAL`  | Login form displayed                        |
| 4     | `SUBMIT_CREDENTIAL`          | User submitted credentials                  |
| 5     | `COMPONENT_LOAD_MFA`         | MFA question displayed (if applicable)      |
| 6     | `SUBMIT_MFA`                 | User answered MFA (if applicable)           |
| 7     | `REDIRECT`                   | Connection successful — `loginId` available |

Listen for the `REDIRECT` event to capture the `loginId` and proceed with your backend flow.

## Deep link configuration

If you use a `redirectUrl` parameter, ensure your app is configured to handle the redirect URL as a deep link. This allows the WebView (or OS) to route the user back to your app after a successful connection.

For iOS, register a URL scheme or Universal Link. For Android, configure an intent filter in your `AndroidManifest.xml`.

<Note>
  When using `webview=true`, Flinks Connect sends events via `postMessage` instead of redirecting the URL. You can listen for these events directly in your WebView's message handler rather than relying on URL-based redirects.
</Note>

## OAuth popup handling

Some financial institutions use OAuth for authentication, which opens a popup window. WebViews block popups by default.

**Solutions:**

* Set `javaScriptCanOpenWindowsAutomatically = true` (required on all platforms)
* Use the `oauthWindowRedirect=true` parameter to replace popups with full-page redirects within the WebView

```url theme={null}
https://[instance]-iframe.private.fin.ag/v2/?webview=true&oauthWindowRedirect=true&redirectUrl=https://example.com/callback
```

## Responsive CSS for iframe embedding

If you're embedding Flinks Connect in a hybrid app using an iframe inside a WebView, use responsive CSS to ensure it fills the viewport:

```html theme={null}
<style>
  body, html {
    margin: 0;
    padding: 0;
    height: 100%;
    width: 100%;
  }
  iframe {
    width: 100%;
    height: 100%;
    border: none;
  }
</style>

<iframe
  src="https://[instance]-iframe.private.fin.ag/v2/?webview=true&demo=true"
  allow="clipboard-write; fullscreen"
></iframe>
```

## Testing

Use `demo=true` in your URL to display the test institution **Flinks Capital**. This allows you to test the full connection flow without using real banking credentials. See [Test Users](/guides/connect/flinks-connect/test-users) for available test credentials.
