Put Lexy in your mobile app
The same widget, games and reader accounts inside your iOS, Android, React Native or Flutter app, with no SDK to install.
Your readers are on their phones, and many of them read you inside your app. Lexy goes there with them. The widget you already put on your site works inside your iOS, Android, React Native or Flutter app, so readers get the same games, the same account and the same scores on every screen.
There is no SDK to install and nothing new to sign up for. The embed code is the same one your site uses. Your app team turns on a few web view settings, and that's it.
What readers get in your app
- The same games. The quiz on an article in your app is the same quiz as on that article on your site. Plays and scores count in the same stats.
- The same account. A reader can sign in from the card in your app with the same free Lexy account they use on the web. Their scores follow them.
- Lexy's voice. Lexy reads every question and answer out loud, just as she does on your site.
- A call when they want one. Call Now to Play works in the app too. The reader enters their number and Lexy calls them. Nothing in your app needs to dial.
- Their language. The card and everything in it follow the widget's language, right to left in Arabic.
What's included
| Feature | In your app |
|---|---|
| Game cards, Auto widget, gated card, News Brief, Profile widget | Yes, from the same embed code |
| Tapping answers | Yes, always |
| Lexy reading questions out loud | Yes. Without the sound setting below, the reader taps once to hear her |
| Answering out loud | Where the app's web view can recognize speech. Readers tap otherwise |
| Reader sign-in | Yes, by a six-digit code sent to the reader's email |
| Call Now to Play | Yes. Lexy calls the reader's phone |
| Ads in your games | Yes, the same as on your site |
How sign-in works inside an app
On your site, Sign In opens a small Lexy window. Inside an app, that window can't open, and Google doesn't allow its sign-in inside an app's web view at all. So Lexy changes the way readers sign in when it finds itself in an app.
- The reader taps Sign In. A panel covers the card and asks for their email address.
- They tap Send code, and Lexy emails a six-digit code. The code is in the email's subject line, so it can show on the lock screen.
- They type the code, or tap it above the keyboard on phones that offer it. Six digits sign them in by themselves.
- The card says "Signed in as" and their name, and their score saves.
A reader with no Lexy account gets a free one the moment they enter the code. A code works for 10 minutes. Send a new code sends another, and Use a different email starts over.
The same panel appears in social apps' browsers, like Facebook, Instagram, TikTok and LinkedIn, when a reader opens one of your articles from a post. You don't need to do anything for that.
Add Lexy to your app
How you add it depends on how your app shows an article.
Your app opens article pages from your site
If your app loads your article pages from your site in a web view, Lexy is already there. The embed code on the page does the work. Turn on the settings below and you're done.
Your app builds article pages itself
Many apps put the article's text into their own page template. Add the embed code to that template, just as you would on your site, and add two things.
- Your site's address as the page's base URL. If your widget has an Allowed Domain, Lexy only plays on pages from that domain. A page your app builds on the phone has no address of its own unless you give it one.
- The article's canonical link. Lexy's Auto widget knows an article by its
<link rel="canonical">. With it, the article in your app gets the same quiz as the same article on your site, and its plays count together.
<link rel="canonical" href="https://example.com/news/the-article">
<lexy-widget id="your-widget-id"></lexy-widget>
<script src="https://cdn.lexy.fm/js/widget.js" async></script>
The Auto widget makes its quiz from the article on the page, so the template needs the article's full text, not just a summary.
Web view settings for your app team
iOS (WKWebView)
let config = WKWebViewConfiguration()
config.allowsInlineMediaPlayback = true
config.mediaTypesRequiringUserActionForPlayback = []
config.websiteDataStore = .default()
let webView = WKWebView(frame: .zero, configuration: config)
webView.uiDelegate = self
// a page your app builds: give it your site's address
webView.loadHTMLString(articleHTML, baseURL: URL(string: "https://example.com/"))
- Sound.
mediaTypesRequiringUserActionForPlayback = []lets Lexy start reading without an extra tap. Without it, the reader taps once to hear her. - Video.
allowsInlineMediaPlayback = truekeeps video playing in the page instead of full screen, where the gated card can follow it to unlock questions. - Staying signed in. The default data store keeps the reader signed in between launches. A non-persistent store signs them out every time.
- Answering out loud. Add
NSMicrophoneUsageDescriptionandNSSpeechRecognitionUsageDescriptionto yourInfo.plist, with a line saying Lexy listens for spoken answers. - Links. Lexy opens some links in a new tab, like My Profile in the account menu. Open those in Safari from your
WKUIDelegate.
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration,
for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if let url = navigationAction.request.url { UIApplication.shared.open(url) }
return nil
}
Android (WebView)
webView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
webView.settings.mediaPlaybackRequiresUserGesture = false
// a page your app builds: give it your site's address
webView.loadDataWithBaseURL("https://example.com/", articleHtml, "text/html", "utf-8", null)
- Storage.
domStorageEnabledis off by default on Android. Without it, readers can play, but signing in doesn't stick. - Sound.
mediaPlaybackRequiresUserGesture = falselets Lexy start reading without an extra tap. - Links. Lexy opens some links in a new tab, like My Profile in the account menu. Android opens those inside your web view unless you send them to the browser from your
WebViewClient. - Answering out loud. To let Lexy listen where the web view supports it, add the
RECORD_AUDIOpermission to your manifest, ask for it at run time, and grant audio capture tolexy.fmin yourWebChromeClient.
webView.webChromeClient = object : WebChromeClient() {
override fun onPermissionRequest(request: PermissionRequest) {
val host = request.origin.host ?: ""
val lexy = host == "lexy.fm" || host.endsWith(".lexy.fm")
if (lexy && request.resources.contains(PermissionRequest.RESOURCE_AUDIO_CAPTURE)) {
request.grant(arrayOf(PermissionRequest.RESOURCE_AUDIO_CAPTURE))
} else {
request.deny()
}
}
}
React Native and Flutter
Both show pages in the same web views, so the same settings apply.
- React Native (
react-native-webview): setallowsInlineMediaPlayback,mediaPlaybackRequiresUserAction={false}anddomStorageEnabled, and usesource={{ html, baseUrl: "https://example.com/" }}for a page your app builds. - Flutter (
webview_flutter): set the JavaScript mode to unrestricted, which is off by default, then apply the iOS and Android settings above through each platform's controller.
Check it on a phone
- Open an article with Lexy on it in your app.
- Tap Play the quiz. Lexy should start reading the first question.
- Finish the game and tap Sign in with Lexy. You should get the email code panel, not a blank screen.
- Enter the code from your email. The card says "Signed in as" and your name.
- Close the app and open the article again. You should still be signed in.
If the card stays blank or says the game isn't available, check two things. The page's address must be on the widget's Allowed Domain (see the base URL under Your app builds article pages itself), and the widget must be live on My Widgets.
Common questions
Do we need a Lexy SDK?
No. Lexy runs in the web view your app already has, from the same embed code as your site. There's nothing to add to your app's build, and Lexy's updates reach your app as soon as they reach your site, with no app release.
Do plays in our app count in our stats?
Yes. They count with your widget's plays, the same as plays on your site. A reader who signs in on their phone and their laptop counts as one player in My Players.
Why can't readers sign in with Google inside our app?
Google doesn't allow its sign-in inside an app's web view. That's why Lexy uses an emailed code there. On your site, the Google, Apple and Microsoft buttons work as usual. See Let readers sign in on your site.
Our app needs something native. Can you help?
Yes. Tell us what your app needs at support@lexy.fm.
Thanks for letting us know.
Thanks. Write to support@lexy.fm with what you were looking for, and we will answer and improve this page.