How do I add an App Icon?

You can upload a new icon in your App Configuration page. You'll find it as the first item under "General Styling". Check out our documentation page App Icon regarding the specific dimensions of your app icon here, and our Blog article on designing a mobile app icon.

What are the privacy and security implications of using Median?

By design all data and network traffic from your app goes directly to your web server, exactly as it would if the user browsed your website via Mobile Safari or Mobile Chrome. No website data whatsoever passes through any Median servers, and your app does not depend on Median's servers or uptime to function. Therefore, your app relies on the same security, encryption, and access that exists on your website and SOC 2 compliance is not applicable.

At times clients will require an independent security audit of their app for compliance purposes. Each app created using Median must be audited individually given the hybrid nature of the native app code plus web code, potential use of native plugins, as well as continual updates to the Median solution. Median’s engineering team is available to support these reviews for a nominal fee.

A vendor that several of our enterprise clients have used with success to audit their Median apps is Appknox. (No affiliation or relationship with Median).

Median offers a Jailbreak/Root Detection Native Plugin that detects if an app is running on an insecure jailbroken iOS device or rooted Android device. This native plugin will ensure your app meets compliance requirements and can also be customized based on specific requirements.

Through custom development Median can implement additional measures to further enhance app security and privacy:

  • Apple App Transport Security (ATS)
  • Disable console printing of debug information
  • SSL CA Validation and Certificate/Identity Pinning
  • Prevent copy and paste
  • Block recording of screen activity

When browsing the Median website, using our App Studio platform, and making online purchases note that our SSL certificates are validated as secure for sending and receiving sensitive data by DigiCert.

Which versions of Android and iOS will my app support?

The core Median app supports iOS 12.5+ and Android 8.1+ including both phones and tablets.

Support for Push Notification providers and Native Plugins vary by the SDKs and device functionality required.

We continually release updates to support the latest operating system updates and new devices.

How do I integrate my app with a third-party SDK?

Integration with SDKs from third-party vendors is a differentiating reason to build an app with Median. Our engineering team will integrate the required SDK within our App Studio Build platform for iOS and/or Android so that the SDK is incorporated automatically during each build of your app.
We will work with you to define specifications for accessing the functionality offered by the SDK through the Median JavaScript Bridge. We have extensive experience integrating push notification providers, analytics tools, video and media providers, and more. Contact us for details.

Why is my app crashing at launch?

The most likely cause of this issue is a syntax error in your app's configuration.

This is more likely if you are editing your appConfig.json app configuration file directly through your app's source code, though it could also happen if you've edited your app's configuration via the Build & Export section via our website.

Most importantly, your app's configuration file must be a valid JSON.

If your appConfig.json looks fine, and your app is still crashing, please contact our support team to troubleshoot further.

How do I fix blank page or Invalid SSL connection errors?

For websites with HTTPS or SSL, if you are noticing blank pages or errors that mention SSL connection errors, please verify your SSL certificates are set up correctly.

We also suggest you inspect the Javascript console of your website, because if your website loads javascript, css, or image resources from other domains which themselves have SSL misconfiguration, then that can also cause this error to appear on your site.

You may enter your website domain at to verify your SSL certificate configuration.

Note: Even some domains with Grade A may have warnings listed under the grade (see image below).

Issues may include:

  • Certificate expired (fix by re-issuing)
  • Certificate chain incomplete (fix by adding intermediate certs)
  • Certificate or intermediate signed by SHA-1 (fix by re-issuing and/or updating intermediate certs)
  • Certificate signed by Symantec brands including Verisign, Geotrust, RapidSSL, and Thawte (fix by re-issuing and updating intermediate certs)

Changes to my website are not showing up in my app?

Native apps built using Median obey the same cache headers as a browser, which are sent by your web server. It may take a few minutes, but website changes will update properly. This makes updating the content displayed within your app very easy, as you will just need to update your website.

If you are experiencing delays seeing the website changes in your app, please first wait a few minutes, as often browser caches do have a short delay in updating the latest content from the server. Please also try refreshing the page to load the new content.

If after some time you have not seen the changes, you may want to inspect the cache headers that your web server is sending, which are likely telling the app to cache the resource much longer than intended.

Other strategies include using suffixes on resource files on your website, such as application_782374982.js, where the number gets changed every time you update that file. This forces the browser, and your app, to retrieve the new resource file directly from the server and not rely on the cached file.

You may also completely uninstall and reinstall the app to force a clearing of all cached data for your app.

We have an extra configuration option on Android only to clear the Webview cache every time the app is exited. To enable this feature, you must add "androidClearCache" : true under "general" section in appConfig.json, or in Build & Export section when editing your app. For example:

"general": {
  "androidClearCache": true

There is also a Median JavaScript Bridge command to clear cache via JavaScript: Clear Webview Cache

If the problems persist even after all of these steps, please contact our support team and we can provide further guidance.

How can I debug my website running inside my Android and iOS apps?

You can perform limited debugging of your website when it is displayed in the webview within your app using our browser based simulators. Create a build of your app with Web Logs enabled on the Build & Download tab under Development Tools. The JavaScript Console for the webview within your app will then be streamed to the app log where error messages as well as console output can be viewed. For complete instructions see Development Tools.

For more advanced debugging including inspection of HTML/CSS and live access to the JavaScript console for code execution you may use Safari and Chrome remote debugging. This provides comparable functionality to a regular desktop browser. You may inspect HTML and CSS and make live changes to test differences in display behavior between iOS WKWebView and Android WebView, and you can view JavaScript variables and execute code in realtime.

For iOS please review - it is the same process for Webviews running within your app. Your app must be running on iOS Simulator locally, or on a device plugged into your computer.

For Android please review

To remotely debug on Android, you will need a "debug" build of your app. By default, Median generates a "release" build so that you can publish directly to Google Play with no changes required. To build a "debug" version you will need to build locally referring to Build Android from source. When using push notifications and other integrations that depend on the Android Package Name you must ensure that you build locally using the proper package name that is registered e.g. and not

Why does SpeechSynthesis or other JavaScript methods not work in my app?

The WKWebView and Android System WebView components used within your iOS and Android apps do not necessarily support all JavaScript functionality that is supported within other web browsers. These components are a dependency from Apple and Google and compatibility with JavaScript and CSS varies by iOS and Android version. We recommend referring to the Mozilla developer docs which provide the most comprehensive compatibility tables showing support for specific methods and properties.

For specific functionality concerns we recommend reviewing the WebKit and Chromium Blink bug/issue trackers.

For many methods such as Blob and Geolocation functionality we provide shim code within the app to translate JavaScript methods into an integration with native iOS and Android methods. For more complex functionality such as text-to-speech (TTS) custom development by our team is required to provide an integration that meets your specific requirements.

As part of Median’s full service offerings we work to provide customers full-feature native apps powered by web content and to ensure compatibility across web/iOS/Android. As part of our services we will add advanced native features to webview apps using our platform including integrating with external hardware such as Bluetooth devices.

How do I fix display scaling and prevent zooming?

One of the most glaring UI issues that comes with viewing a website in a mobile app is the scale of the content on the page. When not correctly configured users will have to zoom in to fill out fields, read/watch content or click buttons. To remedy this, ensure that text and UI elements are set to a suitable size, fix the display scaling at 1:1, and prevent zooming by the user. This will result in the smooth user experience expected within a native app.

To fix the display scaling and prevent zooming on your website add the following meta tag to each page:

<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">

How do I add multilingual support to my app?

By default your user's default device language will be set within your app. Your web content will then display in the corresponding language in the same manner it will be displayed in a regular browser, i.e. if there is an Accept-Language header present. This will function for any standard language code without limitation.

The native UI components in the native app layer such as the OK button have been localized to various languages as contributed by customers: ar, ca, cs, da, de, en, es, es-419, fi, fr, gd, he, hu, it, nl, nn-NO, pt-BR, pt-PT, tr

If a language you require is not listed please get in touch with our team and we will be happy to add support.

How do I prevent text selection in my app?

Preventing selection of text on your web pages when they are being presented within your app will result in a more app-like experience for users. This is particularly true for UI elements such as buttons.

We recommend adding the CSS below to each page. Change body and a to the elements you wish to target.

 body, a{
   -webkit-touch-callout: none !important;
   -webkit-user-select: none !important;
   -khtml-user-select: none !important;
   -moz-user-select: none !important;
   -ms-user-select: none !important;
   user-select: none !important;
   -webkit-tap-highlight-color: transparent !important;

How do I display or download files in my app, such as PDF or JPG?

Your app will follow the standard Content-Disposition header sent by your server to either display a file inline within the webview of your app or to automatically download the file as an attachment:

  • Content-Disposition: inline - Files sent with this header will be displayed in the app webview similar to any other HTML content. You may need to use Native Navigation to provide a way for your users to navigate from the file to elsewhere within your app.
  • Content-Disposition: attachment - Files sent with this header will be automatically downloaded to the user's device. On iOS the "Share" dialog will be invoked so the user can open with the Files app. On Android the user will be provided an option to open the file.

If you are not able to set the Content-Disposition header you may use the JavaScript Bridge Download File functions to download files. You can also use the Download Image functions to automatically save images to the user's photo library/gallery.

How do I change the title text in the top navigation bar

You can add the following to each page for which you wish to set a title.

function median_library_ready(){
  median.navigationTitles.setCurrent({'title':'Your Title'});

For more details refer to Dynamic Titles.

How can I disable Cleartext permission to disallow insecure network traffic?

If you only want to allow encrypted network traffic such as HTTPS on your app and disallow traffic from HTTP which contains unencrypted cleartext, you can open the Import / Export section of your app, edit the network object in appConfig.json's security object and specify "allowInsecure": false. If the security object is missing in your appConfig.json, you can create it as shown in the example below:

"security": {
    "network": {
        "allowInsecure": false

I receive the error "App Not Installed" when testing my Android app

This installation error message can sometimes occur when testing your pre-release Android app on a physical device. Importantly, once your app is uploaded and distributed through Google Play Store, this will no longer be an issue. But, how can you fix it for testing?

For each Android package name, i.e., in order to install it onto your device, it must have a higher "version code" than any previously installed version. This is the case even if you uninstall the app completely.

If you generate your APK through the website, we automatically increment the "version code" each time your app builds. This is fine, because it's never visible to your end users, and is a number that's only used internally. The version that your users see is something different, called "version name".

So how can this occur?

  1. We've seen this occur if you install your APK from the website with version code #7, then uninstall it from device, then try to re-install the same APK.
  2. If you are building from source code locally, and you do not increment versionCode in your app's build.gradle file.
  3. Some other odd reason we are still unsure of!

If it does occur, and rebuilding via our website or changing the version code does not seem to help, then we've heard some clients have success with temporarily disabling Google Play Protect. We've not tested this method ourselves, so please use it at your own discretion. More info about that at

How can I keep my app users logged in?

Login behavior within your app will mirror that of your website. In short, we recommend setting a persistent login cookie.

Session cookies, which can be used to keep a user logged in while they navigate from page to page within your website, will expire at the end of the session. This happens when the user logs out of your site manually, but also when the user quits their web browser. 

Persistent cookies can also be used to keep a user logged in while they navigate your site. What's different about persistent cookies is that even if the user quits their web browser, when they go back to your website the cookie will still exist and the user can then be automatically logged in. 

Of course, any invalidation of cookies, or timeouts, on your server side would render these cookies ineffective whether they are session or persistent cookies. 

The behavior of these cookies will work similarly in your apps. If you would like your users to be automatically logged in when they open up the app, even after quitting the app or restarting their device, please use persistent cookies for this purpose.

How can I configure my app to work offline?

Most clients these days are comfortable with their app requiring a network connection. But we also understand the desire for your app to work offline.

Previously, both Android and iOS platforms supported HTML5 Cache Manifest. However, this is now deprecated on iOS and it will only work on Android. 

Service Workers

Service Workers have emerged as the new standard on the web that supports offline functionality. If you implement Service Workers on your website to support offline access, the same will work in your Median apps. In Android by default and in iOS subject to the following requirements. Service Worker support for WKWebView was only added in iOS 14, and only when using App Bound domains which require customization of your app.

You may implement in your iOS source code directly, or we can provide this support on iOS with custom development for a small fee. 

In addition to Service Workers, we do have a premium add-on called Download Manager that works well for downloading specific files to be available offline. Please see our documentation Offline Download Manager.

We also have a solution called OfflineSync that will work only if your app can work 100% offline without any network connectivity whatsoever, such as for a sales catalog, or an in-store kiosk display. Please contact us if interested in OfflineSync.

Can I use an alternate WebView component within my Android app rather than System WebView?

Yes. There are known limitations with the built-in Android System WebView such as:

  • Resources are shared across all apps that are using the System WebView component
  • During an update of System WebView all instances of WebView are stopped causing apps using WebView to crash
  • Edge case bugs remain open such as delays in user input which can cause poor UX for some apps

Median’s engineering team are able to implement a custom WebView component that is embedded directly in your app, rather than relying on the shared Android System WebView. We recommend GeckoView. You can learn more about WebView limitations and solutions via the Facebook Developer blog. Note however that when using an embedded WebView component the app binary size will be much larger than an app that uses the Android System WebView.