Google ads in Wordpress JSON feed automatically spawn browser when the Flutter WebView loads
I have a Flutter newsreader app that uses a WordPress JSON feed for its content. Im using Advanced Ads Wordpress plugin and its injecting the same ads that are on the web into the JSON Feed with the post content.
When my WebView loads it automatically spawns an external browser. This is without user interaction. The ads are loading fine in the webview. I had the same issue with youtube but applying the same solution to the google ads URL does not work.
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; import 'package:url_launcher/url_launcher.dart'; import 'data.dart'; // Post model import 'html.dart'; // For building HTML content import 'package:share_plus/share_plus.dart'; // Import share_plus class PostDetailScreen extends StatefulWidget{ final Post post; final List<Post> recentPosts; const PostDetailScreen({Key? key, required this.post, required this.recentPosts}) : super(key: key); @override PostDetailScreenState createState() => PostDetailScreenState(); } class PostDetailScreenState extends State<PostDetailScreen>{ late WebViewController _controller; String htmlContent = ''; bool isLoading = true; @override void initState() { super.initState(); loadContent(); } Future<void> loadContent() async { String encodedVisbyFont = await loadEncodedFont(); String encodedCanelaFont = await loadCanelaFont(); htmlContent = buildHtmlContent( widget.post.imageUrl, widget.post.title, widget.post.content, widget.post.author, widget.post.modified, encodedVisbyFont, encodedCanelaFont, widget.recentPosts.take(10).toList() ); setState(() { isLoading = false; }); } Future<void> updatePostContent(String postLink) async { final selectedPost = widget.recentPosts.firstWhere( (post) => post.link == postLink, orElse: () => widget.post, ); String updatedContent = buildHtmlContent( selectedPost.imageUrl, selectedPost.title, selectedPost.content, selectedPost.author, selectedPost.modified, await loadEncodedFont(), await loadCanelaFont(), widget.recentPosts.take(10).toList(), ); setState(() { htmlContent = updatedContent; }); _controller.loadUrl(Uri.dataFromString( htmlContent, mimeType: 'text/html', encoding: Encoding.getByName('utf-8'), ).toString()); } @override Widget build(BuildContext context) { final bool tablet = MediaQuery.of(context).size.width > 600; final double titleFontSize = tablet ? 36.0 : 24.0; final double iconSize = tablet ? 36.0 : 30.0; final EdgeInsetsGeometry iconPadding = tablet ? const EdgeInsets.all(12.0) : const EdgeInsets.all(8.0); final double appBarHeight = tablet ? 70.0 : 56.0; return Scaffold( appBar: PreferredSize( preferredSize: Size.fromHeight(appBarHeight), child: AppBar( title: Text( 'FRENCHLY', style: TextStyle( fontFamily: 'Oswald', fontSize: titleFontSize, fontWeight: FontWeight.bold, color: Colors.white, ), ), backgroundColor: const Color(0xFF1D5986), centerTitle: true, iconTheme: IconThemeData(color: Colors.white, size: iconSize), actions: <Widget>[ Padding( padding: iconPadding, child: IconButton( icon: Icon(Icons.share, color: Colors.white, size: iconSize), onPressed: () { Share.share('${widget.post.title}\n\n${widget.post.link}'); }, ), ), ], ), ), body: isLoading ? const Center(child: CircularProgressIndicator()) : WebView( initialUrl: Uri.dataFromString( htmlContent, mimeType: 'text/html', encoding: Encoding.getByName('utf-8'), ).toString(), javascriptMode: JavascriptMode.unrestricted, onWebViewCreated: (WebViewController controller) { _controller = controller; }, navigationDelegate: (NavigationRequest request) async { if (request.url.startsWith('post://')) { final postLink = Uri.decodeFull(request.url.substring(7)); updatePostContent(postLink); return NavigationDecision.prevent; } else if (request.url.contains('youtube.com') || request.url.contains('youtu.be')) { // Load YouTube URLs in the WebView itself return NavigationDecision.navigate; } else if (await canLaunchUrl(Uri.parse(request.url))) { await launchUrl(Uri.parse(request.url), mode: LaunchMode.externalApplication); return NavigationDecision.prevent; } return NavigationDecision.navigate; }, ), ); } }
This ened up working for me:
navigationDelegate: (NavigationRequest request) async {if (request.url.startsWith('post://')) { final postLink = Uri.decodeFull(request.url.substring(7)); updatePostContent(postLink); return NavigationDecision.prevent; } else if (request.url.contains('youtube.com') || request.url.contains('youtu.be')) { // Load YouTube URLs in the WebView itself return NavigationDecision.navigate; } else if (request.url.contains('googlesyndication.com')) { // Load Google Ad URLs in the WebView itself return NavigationDecision.navigate; } else if (await canLaunchUrl(Uri.parse(request.url))) { await launchUrl(Uri.parse(request.url), mode: `enter code here`LaunchMode.externalApplication); return NavigationDecision.prevent; } return NavigationDecision.navigate; },