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

# The Connect Widget

Connect is a ready-made and embeddable application that allows you to quickly add members to Atrium and navigate the complex aggregation process. It searches for institutions, creates new members, gathers credentials, prompts for MFA, resolves errors, and can start verification and aggregation jobs.

You can use Connect by embedding it in a website with an iframe or a mobile application with a WebView.

## Get a Connect Widget URL

To get started with the Connect Widget, you will first need to create a user and then get a widget URL by making a `POST` request to [`/users/{user_guid}/connect_widget_url`](/api-reference/platform-api/reference/widgets). You can also use one of our [wrapper libraries](https://github.com/mxenabled?q=atrium\&type=\&language=) to make this request.

## Configuration and Integration

For complete information on correctly configuring and integrating the Connect Widget into your website or app, please see our comprehensive Connect reference. Examples in this reference use the Platform API, but all configuration options and details in the integration guides apply to Connect in the Atrium API as well.

## Embedding in Webviews

Because of the technical limitations of WebView-based implementations, an alternative to standard postMessages is required. If Connect is configured with `is_mobile_webview` set to `true`,  we will use navigation events with `window.location = url` instead of `window.postMessage(message)`

`ui_message_webview_url_scheme` will be `atrium://` by default.

<Warning>
  **WARNING**

  Your app will need to prevent all navigation events to `ui_message_webview_url_scheme://` and `atrium://` so the WebView doesn't lose the Connect session.
</Warning>

**Example navigation event schema**

`{ui_message_webview_url_scheme}://{some/path}?metadata={jsonString}`

```shell Request theme={null}
# Suggested base configuration for WebViews.
curl -i -X POST 'https://vestibule.mx.com/users/{user_guid}/connect_widget_url' \
  -H 'Accept: application/vnd.mx.atrium.v1+json' \
  -H 'Content-Type: application/json' \
  -H 'MX-API-Key: {mx_api_key}' \
  -H 'MX-Client-ID: {mx_client_id}' \
  -d '{
        "is_mobile_webview": true,
        "ui_message_version": 4,
        "ui_message_webview_url_scheme": "yourAppScheme"
      }'
# Possible navigation events based on the config above:
# `atrium://load`
# `yourAppScheme://connect/institutionSearch?metadata={...json...}
```

**Example URL capture**

<CodeGroup>
  ```java Java theme={null}
  public class MainActivity extends AppCompatActivity {
      private WebView webView = null;
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        webView = (WebView) findViewById(R.id.webview);
        webView.setWebViewClient(new AtriumWebViewClient());
        webView.getSettings().setDomStorageEnabled(true);
        webView.getSettings().setJavaScriptEnabled(true);
      }
      private class AtriumWebViewClient extends WebViewClient {
          @Override
          public boolean shouldOverrideUrlLoading(WebView view, String url) {
              if (url.equals("atrium://mxConnectLoaded")) {
                  //Take action here.
                  return true;
              } else if (url.startsWith("atrium://memberAdded")) {
                  //Grab member guid and take action here.
                  return true;
              }
              return false;
          }
      }
  }
  ```

  ```swift Swift theme={null}
  class ViewController: UIViewController, WKUIDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        webView.delegate = self
        ...
    }

    func webView(_ webView: WKWebView, decidePolicyFor
      navigationAction: WKNavigationAction,
      decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void) {

      // Intercept custom URI
      let surl = navigationAction.url?.absoluteString
      if (surl?.hasPrefix("atrium://"))! {
        // Take action here

        // Cancel request
        decisionHandler(.cancel)
        return
      }

      // Allow request
      decisionHandler(.allow)
    }
  }
  ```
</CodeGroup>

## Using OAuth in Connect with WebViews

<Info>
  **INFO**

  All new clients making use of WebViews will need to use the OAuth methods described here. Existing clients will need to adjust their implementations.
</Info>

There are three configuration options WebViews will need in order to have the optimal OAuth flow:

* `is_mobile_webview: true` — Allows the widget to know if it is in a WebView context.
* `ui_message_version: 4` — Allows the widget to send new postMessage events.
* `ui_message_webview_url_scheme: <your app>` — Determines message scheme; this is is used by MX to redirect the user back to the client app in mobile contexts.

**Example request**

```shell Request theme={null}
curl -i -X POST 'https://vestibule.mx.com/users/{user_guid}/connect_widget_url' \
  -H 'Accept: application/vnd.mx.atrium.v1+json' \
  -H 'Content-Type: application/json' \
  -H 'MX-API-Key: {mx_api_key}' \
  -H 'MX-Client-ID: {mx_client_id}'
  -d '{ "is_mobile_webview": true, "ui_message_version": 4, "ui_message_webview_url_scheme": "{app scheme}" }'
```

### Redirecting the User

Since the MX WebView can't reliably send the user from the app to the OAuth provider's site in a native browser, the containing iOS or Android app will need to. To facilitate this, your app will need to react to the `connect/oauthRequested` postMessage request:

`<ui_message_webview_url_scheme>://connect/oauthRequested?metadata=...`

The OAuth URL is inside of the `metadata` query parameter under the `url` key.

**Example redirect**

<CodeGroup>
  ```java Java theme={null}
  /**
   * This Client will capture urls from MX and cancel them. It will specifically
   * handle the oauthRequested URL. You will want to set this client as your
   * WebView's client or add this functionality to your own.
   */
  public class MXWebViewClient extends WebViewClient {
      private Activity activity;

      public MXWebViewClient(Activity mainActivity) {
          activity = mainActivity;
      }

      @Override
      public boolean shouldOverrideUrlLoading(WebView view, String url) {
          // Ensure you are looking for schemes from both 'mx', 'atrium' and whatever you configured
          // ui_message_webview_url_scheme to be. In this example, it was 'appscheme'.
          boolean isFromMX = url.startsWith("mx://")  || url.startsWith("atrium://") || url.startsWith("appscheme://");

          if (isFromMX) {
              try {
                  Uri mxURI = Uri.parse(url);

                  // Handle the oauth url redirect. Send the user to the URL given.
                  if (mxURI.getPath().equals("/oauthRequested")) {
                      JSONObject mxMetaData = new JSONObject(mxURI.getQueryParameter("metadata"));
                      String oauthURL = mxMetaData.getString("url");
                      Uri oauthPage = Uri.parse(oauthURL);
                      Intent intent = new Intent(Intent.ACTION_VIEW, oauthPage);
                      activity.startActivity(intent);
                  }
              } catch (Exception err) {
                  Log.e("sb: Error creating URI", err.getMessage());
              }
              return true;
          }

          return false;
      }
  }
  ```

  ```swift Swift theme={null}
  /**
   * Set up the WebView to capture URLs. You will want to cancel all urls from MX.
   */
  class ViewController: UIViewController, WKNavigationDelegate {

      var webView: WKWebView!
      let appScheme = "appscheme://"
      let mxScheme = "mx://"
      let atriumScheme = "atrium://"

      func webView(_ webView: WKWebView,
                   decidePolicyFor navigationAction: WKNavigationAction,
                   decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void) {

          // Ensure you are looking for schemes from both 'mx', 'atrium', and whatever you configured
          // ui_message_webview_url_scheme to be. In this example, it was 'appscheme'.
          let url = navigationAction.request.url?.absoluteString
          let isFromMX = url?.hasPrefix(appScheme) == true || url?.hasPrefix(mxScheme) == true || url?.hasPrefix(atriumScheme) == true

          if isFromMX {
              let urlc = URLComponents(string: surl ?? "")
              let path = urlc?.path ?? ""
              // there is only one query parameter ("metadata")
              // so just grab the first one
              let metaDataQueryItem = urlc?.queryItems?.first

              if path == "/oauthRequested" {
                  handleOauthRedirect(payload: metaDataQueryItem)
              }

              // Cancel request
              decisionHandler(.cancel)
              return
          }

          // Allow request
          decisionHandler(.allow)
      }

      /*
       * Handle the oauthRequested event. Parse out the OAuth URL from the event
       * and open Safari to that URL
       * NOTE: This code is somewhat optimistic, you'll want to add error handling
       * that makes sense for your app.
       */
      func handleOauthRedirect(payload: URLQueryItem?) {
          let metadataString = payload?.value ?? ""

          do {
              if let json = try JSONSerialization.jsonObject(with: Data(metadataString.utf8), options: []) as? [String: Any] {
                  if let url = json["url"] as? String {
                      // open safari with the url from the json payload
                      UIApplication.shared.open(URL(string: url)!)
                  }
              }
          } catch let error as NSError {
              print("Failed to parse payload: \(error.localizedDescription)")
          }
      }
  }
  ```
</CodeGroup>

### Getting Back To Your App

Once the user completes the OAuth process, MX will send the user back to the client app via a URL scheme like so:

`<ui_message_webview_url_scheme>://oauth_complete?status=<success|error>&member_guid=<guid>`

This part is optional for OAuth, but highly recommended. If this is not set, the user will end on an MX page with a success or error message and will have to navigate back to your app manually. Make sure to pick a scheme that your app can respond to.
