Supercharging Server-Driven Flutter Applications with WebViews built using SvelteKit

Sanjeev JayaSurya S
The Uni Cards Tech Blog
5 min readMay 6, 2023

In the fast-paced world of fintech, businesses are constantly looking for ways to improve their user experience and stay ahead of the competition. One approach to achieve this is using web views to serve specific content, which can speed up the mobile application development process and make it more efficient.

The use of web views allows developers to write and maintain code for certain parts of an application with simple web technologies, such as HTML, CSS, and JavaScript, while still taking advantage of native mobile app features. This hybrid approach brings several benefits:

  1. Code Reusability: With web views, you can use the same codebase for both web and mobile applications, reducing the amount of code you need to write and maintain. This can lead to reduction of time and cost in development cycle.
  2. Ease of Updates: Since web views are served from a remote server, you can easily update the content and fix issues without having to release a new version of your mobile application, improving the agility of your development process.
  3. Platform Consistency: By using web views, you can ensure that the user experience is consistent across different platforms, as the same web-based content is displayed on both Android and iOS devices.
  4. Access to Web Technologies: With web views, you can leverage the rich ecosystem of web technologies and libraries to build feature-rich and interactive components, which can be seamlessly integrated into your mobile application.

What is SvelteKit?

SvelteKit is a full-featured framework built on top of Svelte, designed for building modern web applications. It provides an all-in-one solution for developing web apps with Svelte, streamlining the development process and simplifying the deployment of your applications.

SvelteKit comes with a number of powerful features, such as:

  1. Server-side rendering (SSR): SvelteKit can render components on the server, improving the initial load time and overall performance of an application.
  2. Built-in routing: SvelteKit includes a file-based routing system, making it easy to create and manage routes within an application.
  3. Optimised build outputs: SvelteKit automatically optimizes your build output, resulting in smaller and more efficient bundles for the users to download.

By using SvelteKit, you can harness the power of Svelte’s performance optimisations and ease of use, while also benefiting from the additional features provided by the framework. This makes SvelteKit an ideal choice for creating web views or building full-featured web applications.

Building an App Bridge: Establishing Communication Between Flutter and SvelteKit

When you’re developing a mobile application using this hybrid approach, integrating web content with native functionality is crucial. Webviews allow you to display web content within your mobile app, but you’ll need a way to communicate between your native app and the webview. That’s where an app bridge comes in handy.

An app bridge enables bidirectional communication between the Flutter app and the webview (SvelteKit). This communication channel allows you to send and receive messages, events, and data, resulting in seamless interactions between your mobile app and web content.

Building the app bridge :

Step 1: Set up the WebView in Flutter

First, add the webview_flutter package to your pubspec.yaml file and import it into the file where you'll create the WebView widget. Then, create a StatefulWidget or StatelessWidget using the WebView widget:

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:async';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: WebViewWithMessageHandler(initialUrl: '* your webview url *'),
);
}
}

class WebViewWithMessageHandler extends StatefulWidget {
final String initialUrl;

WebViewWithMessageHandler({required this.initialUrl});

@override
_WebViewWithMessageHandlerState createState() => _WebViewWithMessageHandlerState();
}

class _WebViewWithMessageHandlerState extends State<WebViewWithMessageHandler> {
final Completer<WebViewController> _controller = Completer<WebViewController>();

void _sendMessage() async {
final WebViewController controller = await _controller.future;
controller.evaluateJavascript("window.postMessage('Hello from Flutter', '*');");
}

JavascriptChannel _receiveMessageFromWeb(BuildContext context) {
return JavascriptChannel(
name: 'messageReceiver',
onMessageReceived: (JavascriptMessage message) {
print('Received message from SvelteKit: ${message.message}');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Received message from SvelteKit: ${message.message}')),
);
},
);
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter WebView with PostMessage'),
),
body: WebView(
initialUrl: widget.initialUrl,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
javascriptChannels: <JavascriptChannel>{
_receiveMessageFromWeb(context),
},
),
floatingActionButton: FloatingActionButton(
onPressed: _sendMessage,
child: Icon(Icons.send),
),
);
}
}

_receiveMessageFromWeb : This method creates a JavascriptChannel that listens for messages sent from the SvelteKit app to the Flutter app. The JavascriptChannel is given the name 'messageReceiver', which is used in the SvelteKit app when sending messages. When a message is received in the Flutter app, it triggers the onMessageReceived callback, which prints the message to the console and shows a Snackbar with the received message.

_sendMessage: This method is called when the FloatingActionButton is pressed. It first awaits the completion of the _controller.future to get the instance of WebViewController. After that it posts a message to the window.messageReceiver object using the postMessage method.

Step 2: Implement the App Bridge in SvelteKit

In your SvelteKit repository , set up two routes : sender.svelte and receiver.svelte , one route to send messages to the flutter application and the other to receiver messages from flutter application.

We add an event listener to receive messages sent from the Flutter app. To send messages from the webview to the Flutter app, use the window.parent.postMessage method.

receiver.svelte :

<script>
import { onMount } from 'svelte';

onMount(() => {
window.addEventListener('message', handleMessage);
return () => {
window.removeEventListener('message', handleMessage);
};
});

function handleMessage(event) {
console.log(`Received message: ${event.data}`);
alert(`Received message: ${event.data}`);
}
</script>

<h1>Receiver Page</h1>
<p>This page listens for messages from the Flutter app using the postMessage API.</p>

sender.svelte :

<script>
import { onMount } from 'svelte';

onMount(() => {
window.addEventListener('message', function(event) {
if (event.data.channel === 'messageReceiver') {
window.messageReceiver.postMessage(event.data.message);
}
});
})


function sendMessage(message) {
window.parent.postMessage({channel: 'messageReceiver', message: message}, '*');
}
</script>

<h1>Sender Page</h1>
<p>This page sends messages to the Flutter app using the postMessage API.</p>
<button on:click={() => sendMessage('Hello from SvelteKit')}>Send Message to App</button>
Images post implementation of appbridge in sveltekit and javascript channel in flutter

Congrats! You’ve now successfully built an app bridge to establish communication between a Flutter app and a SvelteKit webview. With this foundation, you can create seamless interactions between your mobile app and web content, improving the user experience and unlocking the full potential of hybrid mobile app development.

Conclusion

SvelteKit provides an excellent solution for implementing webviews in your application. With their performance optimizations, smaller bundle size, and reactive updates, they allow you to create a seamless and engaging user experience. The app bridge ensures smooth communication between your mobile application (built using Flutter) and your webview , making it easy to build a cohesive and powerful server-driven UI application.

--

--