Table of contents
No headings in the article.
The Flutter framework can do much more than you think and is traditionally being used for so many applications platform such as IOS, Android, MacOS, Windows, and Linux apps. Now do you know that Flutter can also create Chrome browser extension apps? Gat ya! now you know! and that's what we will learn how to create with this article. yeah, it's pretty simple.
First, what are Chrome browser extension apps?
Chrome browser extension apps are small-sized programs created and developed for the Chrome browser that can help you experience more functionality while using the Chrome browser.
These browser extensions enhance our activities online when used, though some of them can be used offline too. This article is to learn how to produce them with Flutter and today we will be producing an example app of a QR Code generator.
Let's get Started!
Heads up! this article is not for the absolute Flutter beginners but for someone who has at least used Flutter a little bit and already has it on their machine and has used it to create one or two mini-applications that have rows and columns and other widgets. If you are that person? Dive in!
Let's start by creating our default Flutter counter app by doing:
flutter create qr_code_app
this creates the usual default counter app for us which we will change soon but first let's go to the index.html page on the project web folder in our newly created app and delete some code and also add some new codes.
First, let's delete all the codes inside the <script> tag:
and replace them with these:
So basically what we changed was some blocks of tags, if you look critically at the two sections of the HTML tags you will see them. like for example the height and width of the Chrome browser extension were changed at the top of the HTML tag where we added this:
<!DOCTYPE html>
<html style="height: 350px; width: 650px">
<head>
while inside the </body> tag we changed the block of <script> to the below tag
<body>
<script src="main.dart.js" type="application/javascript"></script>
</body>
After we have changed all the necessary tags in the HTML file we go to the manifest.json file and delete all the blocks of codes there and replace them with the following codes:
{
"name": "QR Code Extension",
"description": "QR Code Extension",
"version": "1.0.0",
"content_security_policy": {
"extension_pages": "script-src 'self' ; object-src 'self'"
},
"action": {
"default_popup": "index.html",
"default_icon": "icons/Icon-192.png"
},
"manifest_version": 3
}
Now it is time to add the QR Code package from pub.dev so we will be using this particular package called QR Flutter. Use the latest version and please read the docs to know how to use it because there might be breaking changes depending on when you are reading this article. once we have added the package to our pubspec.yaml file under dependencies and have called get packages, the package will be automatically downloaded to our project and be ready to use.
Because we want to add some colors to our QRCode maker let's create a constants folder with a color_list.dart file to house some list of colors.
You can copy the code below and put it in the ...constants/color_list.dart file:
import 'package:flutter/material.dart';
const List<Color> qrBackgroundColors = [
Colors.white,
Colors.green,
Colors.blue,
Colors.orange,
Colors.pink,
Colors.red,
];
// for the qr code itself lets add mutltiple colors
const List<Color> qrColors = [
Colors.black,
Colors.blue,
Colors.green,
Colors.brown,
Colors.pink
];
we will use the colors in enhancing the foreground and background of our QRCode.
Now let's go on and create a nice UI for our QR code Chrome extension. You can also copy the code below after creating a pages folder and in it, we create a qr_view.dart file in which we will place the code for our UI part.
so inside our qr_view.dart file we create a stateful widget, some text editing controllers, qrText string, and other widgets as well as importing all necessary imports as shown in the code below.
...Pages/qr_view.dart file:
import 'package:flutter/material.dart';
import 'package:qr_code/constants/color_lists.dart';
import 'package:qr_flutter/qr_flutter.dart';
class QRView extends StatefulWidget {
const QRView({super.key});
@override
State<QRView> createState() => _QRViewState();
}
class _QRViewState extends State<QRView> {
late final TextEditingController _textEditingController;
late final FocusNode _textFocus;
String qrText = '';
int qrColorIndex = 0;
int qrBackgroundColorIndex = 0;
@override
void initState() {
_textEditingController = TextEditingController(text: qrText);
_textFocus = FocusNode();
super.initState();
}
@override
void dispose() {
_textEditingController;
_textFocus;
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16.0,
vertical: 24.0,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: const BoxDecoration(
color: Colors.black54,
borderRadius: BorderRadius.all(Radius.circular(10))),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: QrImageView(
data: qrText,
padding: const EdgeInsets.all(16),
backgroundColor: qrBackgroundColors[qrBackgroundColorIndex],
eyeStyle: QrEyeStyle(
color: qrColors[qrColorIndex],
eyeShape: QrEyeShape.square,
),
foregroundColor: qrColors[qrColorIndex],
),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 24.0,
vertical: 16,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
TextField(
controller: _textEditingController,
focusNode: _textFocus,
decoration: InputDecoration(
labelText: 'QR Text',
labelStyle: const TextStyle(
color: Color(0xFF80919F),
),
hintText: 'Enter URL or Text',
hintStyle: const TextStyle(
color: Color(0xFF80919F),
),
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Colors.black54,
width: 2,
),
borderRadius: BorderRadius.circular(16),
),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Colors.black,
width: 2,
),
borderRadius: BorderRadius.circular(16),
),
),
onChanged: (value) => setState(() {
qrText = value;
}),
),
const SizedBox(height: 24),
const Text(
'Select QR Color',
style: TextStyle(
color: Colors.black,
fontSize: 16,
),
),
Expanded(
child: ListView.separated(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
separatorBuilder: (_, __) => const SizedBox(width: 8),
itemCount: qrColors.length,
itemBuilder: (context, index) {
return InkWell(
hoverColor: Colors.transparent,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: () => setState(() {
qrColorIndex = index;
}),
child: Stack(
alignment: Alignment.center,
children: [
CircleAvatar(
radius: qrColorIndex == index ? 23 : 22,
backgroundColor: qrColorIndex == index
? Colors.black
: Colors.black26,
),
CircleAvatar(
radius: 20,
backgroundColor: qrColors[index],
),
],
),
);
},
),
),
const Text(
'Select QR Background Color',
style: TextStyle(
color: Colors.black,
fontSize: 16,
),
),
Expanded(
child: ListView.separated(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
separatorBuilder: (_, __) => const SizedBox(width: 8),
itemCount: qrBackgroundColors.length,
itemBuilder: (context, index) {
return InkWell(
hoverColor: Colors.transparent,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: () => setState(() {
qrBackgroundColorIndex = index;
}),
child: Stack(
alignment: Alignment.center,
children: [
CircleAvatar(
radius:
qrBackgroundColorIndex == index ? 23 : 22,
backgroundColor:
qrBackgroundColorIndex == index
? Colors.black
: Colors.black26,
),
CircleAvatar(
radius: 20,
backgroundColor: qrBackgroundColors[index],
),
],
),
);
},
),
),
const SizedBox(height: 16),
],
),
),
)
],
),
),
);
}
}
Great!
Now we go to the main.dart file and change the Homepage to the QRView page widget we just created like so:
import 'package:flutter/material.dart';
import 'package:qr_code/Pages/qr_view.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'QR Code Maker',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const QRView(),
);
}
}
Now we are done with the coding part. It's now time to configure our Google Chrome Browser.
so to start, let's build our new app on Chrome by running this simple code on the terminal of our VS code
flutter run -d Chrome
This will launch our newly created app on the Chrome browser.
Another way is to select Chrome as the device on your VS code editor bottom bar and then run the code.
To get our app running as a Chrome browser extension, we have to go to this URL on our Chrome browser :
Then click on developer mode.
After that, go to your Flutter terminal in the root folder and run the following command
flutter build web --web-renderer html --csp
This will build the app for you. in your [ ...build/web ] folder of your project;
then go back to Chrome and click Load unpacked:
Then you will go to the build/web folder of your Flutter project and select the web folder which will load the newly created app and produce this new extension shown below
Then we click on the Chrome extension icon to find our newly created QRCode extension app
And you will get something like this
Hurray! you now have your app working perfectly.
END.
Thank you for reading. More will be coming up soon.
You can find the complete project here on my GitHub Please note that the project might change a little as I might still modify it from time to time.
Reference: