A feature-rich cross-platform webview using webview_flutter for mobile and iframe for web. JS interop-ready.

Related tags

Templates webViewX
Overview

webviewx

pub package

A feature-rich cross-platform webview using webview_flutter for mobile and iframe for web. JS interop-ready.

Getting started


Gallery

Mobile

Web


Basic usage

1. Create a WebViewXController inside your stateful widget

late WebViewXController webviewController;

2. Add the WebViewX widget inside the build method, and set the onWebViewCreated callback in order to retrieve the controller when the webview is initialized

WebViewX(
    initialContent: '

Hello, world!

'
, initialSourceType: SourceType.HTML, onWebViewCreated: (controller) => webviewController = controller, ... ... other options );

Important !

If you need to add other widgets on top of the webview (e.g. inside a Stack widget), you MUST wrap those widgets with a WebViewAware widget. This does nothing on mobile, but on web it allows widgets on top to intercept gestures. Otherwise, those widgets may not be clickable and/or the iframe will behave weird (unexpected refresh/reload - this is a well known issue).

Also, if you add widgets on top of the webview, wrap them and then you notice that the iframe still reloads unexpectedly, you should check if there are other widgets that sit on top without being noticed, or try to wrap InkWell, GestureRecognizer or Button widgets to see which one causes the problem.

3. Interact with the controller (run the example app to check out some use cases)

webviewController.loadContent(
    'https://flutter.dev',
    SourceType.url,
);
webviewController.goBack();

webviewController.goForward();
...
...

Features

Note: For more detailed information about things such as EmbeddedJsContent, please visit each own's .dart file from the utils folder.

  • Widget properties

Feature Details
String initialContent Initial webview content
SourceType initialSourceType Initial webview content type (url, urlBypass or html)
String? userAgent User agent
double width Widget's width
double height Widget's height
Function(WebViewXController controller)? onWebViewCreated Callback that gets executed when the webview has initialized
Set jsContent A set of EmbeddedJsContent, which is an object that defines some javascript which will be embedded in the page, once loaded (check the example app)
Set dartCallBacks A set of DartCallback, which is an object that defines a dart callback function, which will be called from javascript (check the example app)
bool ignoreAllGestures Boolean value that specifies if the widget should ignore all gestures right after it is initialized
JavascriptMode javascriptMode This specifies if Javascript should be allowed to execute, or not (allowed by default, you must allow it in order to use above features)
AutoMediaPlaybackPolicy initialMediaPlaybackPolicy This specifies if media content should be allowed to autoplay when initialized (i.e when the page is loaded)
void Function(String src)? onPageStarted Callback that gets executed when a page starts loading (e.g. after you change the content)
void Function(String src)? onPageFinished Callback that gets executed when a page finishes loading
NavigationDelegate? navigationDelegate Callback that, if not null, gets executed when the user clicks something in the webview (on Web it only works for SourceType.urlBypass, for now)
void Function(WebResourceError error)? onWebResourceError Callback that gets executed when there is an error when loading resources ( issues on web )
WebSpecificParams webSpecificParams This is an object that contains web-specific options. Theese are not available on mobile (yet)
MobileSpecificParams mobileSpecificParams This is an object that contains mobile-specific options. Theese are not available on web (yet)

  • Controller properties

Feature Usage
Load URL that allows iframe embedding webviewController.loadContent(URL, SourceType.URL)
Load URL that doesnt allow iframe embedding webviewController.loadContent(URL, SourceType.URL_BYPASS)
Load URL that doesnt allow iframe embedding, with headers webviewController.loadContent(URL, SourceType.URL_BYPASS, headers: {'x-something': 'value'})
Load HTML from string webviewController.loadContent(HTML, SourceType.HTML)
Load HTML from assets webviewController.loadContent(HTML, SourceType.HTML, fromAssets: true)
Check if you can go back in history webviewController.canGoBack()
Go back in history webviewController.goBack()
Check if you can go forward in history webviewController.canGoForward()
Go forward in history webviewController.goForward()
Reload current content webviewController.reload()
Check if all gestures are ignored webviewController.ignoringAllGestures
Set ignore all gestures webviewController.setIgnoreAllGestures(value)
Evaluate "raw" javascript code webviewController.evalRawJavascript(JS)
Evaluate "raw" javascript code in global context ("page") webviewController.evalRawJavascript(JS, inGlobalContext: true)
Call a JS method webviewController.callJsMethod(METHOD_NAME, PARAMS_LIST)
Retrieve webview's content webviewController.getContent()
Get scroll position on X axis webviewController.getScrollX()
Get scroll position on Y axis webviewController.getScrollY()
Scrolls by x on X axis and by y on Y axis webviewController.scrollBy(int x, int y)
Scrolls exactly to the position (x, y) webviewController.scrollTo(int x, int y)
Retrieves the inner page title webviewController.getTitle()
Clears cache webviewController.clearCache()

Limitations and notes

While this package aims to put together the best of both worlds, there are differences between web and mobile.

  • Running and building

    First, this package was being developed while the default web renderer was html. Now(Flutter 2, Dart 2.12), the default renderer is canvaskit.

    From my experience, this package does behave a little bit weird on canvaskit, so you should use the html renderer.

    To do this, you have to run your ordinary flutter run -d chrome command with the --web-renderer html extra argument, like this:

    flutter run -d chrome --web-renderer html

    for running and

    flutter build web --web-renderer html

    for building.

  • Diferences between Web and Mobile behaviour:

    See issues/#27

  • About content loading on Web

    To make the web version (iframe) work as it is, I had to use some of the code from x-frame bypass in order to make a request to a CORS proxy, which removes the headers that block iframe embeddings.

    This might seem like a hack, and it really is, but I couldn't find any other way to make the iframe behave similar to the mobile webview (which is some kind of an actual browser, that's why everything works there by default).

  • About Web navigation

    On web, the history navigation stack is built from scratch because I couldn't handle iframe's internal history the right way.


Known issues and TODOs

  • [ x ] On web, user-agent and headers only work when using SourceType.urlBypass, and they only have effect the first time being used (view/web.dart)

  • [ x ] On web, it should be possible to send any errors caught when loading an urlBypass to a dart callback, which will then be sent through the onWebResourceError callback, just like on the mobile version (utils/x_frame_options_bypass.dart)

  • [ x ] On web, it should be possible to add a custom proxy list without the js null-checking mess (utils/x_frame_options_bypass.dart)

  • [ ? ] Eventually (if possible), most if not all properties from WebSpecificParams and MobileSpecificParams should merge and theese two objects may disappear

  • [ x ] On mobile, the controller's value's source type becomes out of sync when moving back and forth in history. This happens because the url change is not yet intercepted and set the model accordingly (shouldn't be hard to fix).

  • On mobile, the controller's callJsMethod doesnt throw an error if the operation failed. Instead it only shows the error in console.

  • Add tests

  • List open, there may be others

Credits

This package wouldn't be possible without the following:

  • And last but not least, http://deversoft.ro (the company I work for) for motivating me throughout the development process

License

MIT

You might also like...

Random-Face-Generator - A Cross-Platform(Web, Android, iOS) app to Generate Faces of People (These people don't actually exist) made using Flutter

Random-Face-Generator - A Cross-Platform(Web, Android, iOS) app to Generate Faces of People (These people don't actually exist) made using Flutter

👨 👩 Flutter Random Face Generator A flutter app to generate random faces. The

Dec 25, 2022

An instantly ready, full-featured alerts for development on any platform with flutter

An instantly ready, full-featured alerts for development on any platform with flutter

An instantly ready, full-featured alerts for development on any platform with flutter. Enabling you to complete projects and deploy quickly. With QuickAlert, you can display animated alert dialogs such as success, error, warning, confirm, loading or even a custom dialog.

Dec 18, 2022

Croco: Stylized widgets ready to plug into your Flutter Web project

TODO: Put a short description of the package here that helps potential users know whether this package might be useful for them. Features TODO: List w

Jul 7, 2022

Blood Bank is cross platform mobile application that is developed using technologies like Flutter/Dart for frontend and Firebase for data storage

Blood Bank is cross platform mobile application that is developed using technologies like Flutter/Dart for frontend and Firebase for data storage

Blood Bank is cross platform mobile application that is developed using technologies like Flutter/Dart for frontend and Firebase for data storage. The sole goal of this application is to make blood donation resourceful and accessible all round the world.

Nov 5, 2022

Cross Platform mobile application built using Flutter for a group project

splitz A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if this i

Jul 30, 2022

A Flutter plugin that allows you to add an inline WebView.

native_webview A Flutter plugin that allows you to add an inline WebView. Motivation There is already a useful library for working with WebViews in Fl

Dec 14, 2022

Plugin that allow Flutter to communicate with a native WebView.

interactive_webview Plugin that allow Flutter to communicate with a native WebView. Warning: This is not a display WebView. This plugin is designed to

Dec 15, 2022

A complete tutorial series on Flutter webview.

A complete tutorial series on Flutter webview.

Flutter Webview | Tech With Sam Flutter Webview Tutorial - Watch on youtube ✌   App Preview App Screenshot App Screenshot A new Flutter project. Getti

Dec 30, 2022
Owner
null
Rules - Powerful and feature-rich validation library for both Dart and Flutter.

Introduction Rules - Powerful and feature-rich validation library for both Dart and Flutter. Rules is a simple yet powerful and feature-rich validatio

Ganesh Rathinavel 24 Dec 12, 2022
A cross-platform flutter package to convert your links into rich beautiful previews.

Link Preview Generator A cross-platform flutter package to convert your links into rich beautiful previews. This package is inspired from Any Link Pre

Pranav Bedre 12 Oct 21, 2022
DeerNote is a solution for cross-platform rich editor

#DeerNote is a solution for cross-platform rich editor ###DeerNote contains parts as follows: db: mongodb server: nodejs app: flutter launch mongdb se

null 3 Dec 6, 2022
Call Kit is a prebuilt feature-rich call component, which enables you to build one-on-one and group voice/video calls into your app with only a few lines of code.

Call Kit (ZegoUIKitPrebuiltCall) Call Kit is a prebuilt feature-rich call component, which enables you to build one-on-one and group voice/video calls

ZEGOCLOUD 9 Dec 26, 2022
Deepak Sharma 149 Dec 10, 2022
Flutter plugin for playing or streaming YouTube videos inline using the official iFrame Player API

Flutter plugin for playing or streaming YouTube videos inline using the official iFrame Player API. The package exposes almost all the API provided by iFrame Player API. So, it's 100% customizable.

Pratap Singh 0 May 15, 2022
Flutter package to render html as widgets that supports hyperlink, image, audio, video, iframe and many other tags.

HtmlWidget monorepo This repo contains the source code for everything HtmlWidget-related. Name Link flutter_widget_from_html_core flutter_widget_from_

Đào Hoàng Sơn 445 Jan 6, 2023
Dart JS interop for Mermaid - The Javascript tool that makes use of a markdown based syntax to render customizable diagrams, charts and visualizations.

Mermaid (Dart) Dart JS interop for Mermaid - Javascript library that makes use of a markdown based syntax to render customizable diagrams, charts and

Tim Maffett 3 Dec 12, 2022
Cross Platform app in Flutter with Firebase Auth and Firestore. Available for Mobile,Web,Desktop

NavokiNotes Navoki Notes, a note app app, will sync data to cloud and on all devices. We have application for Android, iOS, Web App, PWA, Windows, mac

shivam srivastava 93 Dec 27, 2022
A beautiful cross platform mobile web app use this and ENJOY (2 page) - Flutter UI from scratch

course_app A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if th

Mobin 2 Feb 9, 2022