πŸ“± Webviews
Integration Guide

Integration Guide

Follow the Quick Start first. This page adds platform specifics and operational detail.

Hosted by Lynes

You do not deploy the Webview yourself. Lynes runs a dedicated instance (e.g. https://gamification.your-brand.example.com) connected to your Lynes tenant. Your only integration surface is:

  • Loading that URL in a native WebView
  • Sending a JWT on the initial request
  • Handling the two native callback URLs

1. Choose path and query parameters

The path selects the screen. Query parameters configure language, theme, and back behaviour.

GoalURL pattern
Overview{WEBVIEW_URL}/overview?lang=de&platform=ios
Leaderboard{WEBVIEW_URL}/leaderboard?…&entrypoint=leaderboard
Challenges{WEBVIEW_URL}/challenges?…&entrypoint=challenges
Offers{WEBVIEW_URL}/offers?…&entrypoint=offers
Shops{WEBVIEW_URL}/shops?…&entrypoint=shop

Replace {WEBVIEW_URL} with the base URL from Lynes onboarding.

entrypoint β€” back button only

entrypoint is stored for the browser session and controls when the header back button closes the Webview (via your close callback) and returns the user to your app β€” vs. navigating to the previous screen inside the Webview.

It does not auto-redirect to another route. If the user should land on the leaderboard, load /leaderboard directly and set entrypoint=leaderboard.

Example: user opened from your leaderboard menu β†’ load:

{WEBVIEW_URL}/leaderboard?lang=de&platform=android&entrypoint=leaderboard

From /leaderboard/info, back stays inside the Webview. From /leaderboard with that entrypoint, back triggers your close callback.

Full parameter list: URL Parameters & Routes.

2. JWT on the initial request

Production integrations must send:

Authorization: Bearer <JWT>

on the first document load (the HTML request that opens the Webview).

❌

Do not pass the JWT in the URL

Query parameters like ?token= are not supported for page loads. Tokens in URLs leak via logs and analytics.

iOS (WKWebView)

let webviewURL = URL(string: "{WEBVIEW_URL}/overview?lang=de&platform=ios&darkmode=false")!
var request = URLRequest(url: webviewURL)
request.setValue("Bearer \(jwt)", forHTTPHeaderField: "Authorization")
webView.load(request)

If the user reloads the page or you open a new Webview session, send a fresh JWT again.

Android

val url = "{WEBVIEW_URL}/overview?lang=de&platform=android&darkmode=false"
webView.loadUrl(url, mapOf("Authorization" to "Bearer $jwt"))

3. Session (automatic)

After the first load the Webview:

  1. Stores the JWT briefly in an auth-token cookie (from the Authorization header).
  2. Calls POST /api/token-exchange on the Webview host.
  3. Exchanges the JWT with POST {API_BASE_URL}/auth/token on the Lynes API.
  4. Keeps a session cookie/token for further API calls inside the UI.

You do not call /api/token-exchange from native code.

Details: Authentication.

4. Native callbacks

Register handlers for the exact callback URLs Lynes configured for your deployment (example):

ActionExample URL
Close Webviewmyapp://loyalty/back
Open external linkmyapp://loyalty/external?url=https%3A%2F%2F…

Specification and code samples: Native Bridge.

5. Token refresh

  • Set a sensible JWT exp (e.g. 1 hour).
  • Before opening or reloading the Webview, issue a new JWT if the old one expired.
  • The Webview re-validates the session periodically; expired sessions may navigate to your back callback.

6. Troubleshooting

SymptomLikely causeFix
Endless loading / blank UIMissing or invalid JWT on first loadSend Authorization: Bearer … with valid claims
Wrong userStale JWTNew JWT from your backend before opening Webview
Webview closes too early on backWrong or missing entrypointMatch entrypoint to the feature path (e.g. leaderboard on /leaderboard)
Back never closes the WebviewCallback not implementedHandle your configured …/back URL
External link stuck in Webview…/external not handledDecode url query param and open in browser
Dark mode flashNo darkmode queryAdd darkmode=true or false to the first URL

7. Debug (development only)

GET {WEBVIEW_URL}/api/auth
Authorization: Bearer <JWT>

Returns decoded sub, exp, etc. Not for production page loads.

Related