Nusanet Developers
Published in

Nusanet Developers

Create chrome extension using Flutter

How to create chrome extension using Flutter

Pengenalan

Melihat perkembangan Flutter pada acara Google I/O 2022 kemarin saya benar-benar sangat antusias. Dan benar saja sesuai prediksi saya bahwa tahun ini Flutter desktop sudah benar-benar bisa kita coba di production. Dan untuk Flutter web saya lihat juga sudah lumayan bagus ya performance-nya daripada versi yang sebelumnya. Nah, berhubung si Flutter ini sudah semakin bagus saja perkembangannya saya jadi tertarik untuk membahas Flutter web. Jadi, di tulisan kali ini saya akan coba membahas bagaimana cara membuat extension Google Chrome menggunakan Flutter. Oya, untuk versi Flutter-nya kita nggak perlu pakai yang versi 3 ya. Yang versi 2 saja sudah cukup.

Contoh projek

Untuk contoh projeknya kali ini kita akan membuat extension Google Chrome yang berfungsi untuk membuat QR kode dari teks yang diinput oleh user.

Langkah pertamanya silakan kita buka text editor favorit kita masing-masing terus buat projek baru dengan nama qr_code_chrome_extension.

Buat projek baru

Buka file manifest.json dimana, didalamnya kita bisa lihat kode didalamnya kira-kira seperti berikut ini.

{
"name": "qr_code_chrome_extension",
"short_name": "qr_code_chrome_extension",
"start_url": ".",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"description": "QR code tools for chrome extension",
"orientation": "portrait-primary",
"prefer_related_applications": false,
"icons": [
{
"src": "icons/Icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/Icon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "icons/Icon-maskable-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "icons/Icon-maskable-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}

Kemudian, kita ubah menjadi seperti berikut.

{
"name": "qr_code_chrome_extension",
"description": "QR code tools for chrome 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
}

Catatan: Yang saya tandain bold harap disesuaikan dengan lokal kita masing-masing ya.

Langkah berikutnya ialah kita buka file index.html.

<!DOCTYPE html>
<html>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.

The path provided below has to start and end with a slash "/" in order for
it to work correctly.

For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base

This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`.
-->
<base href="$FLUTTER_BASE_HREF">

<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="QR code tools for chrome extension">

<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="qr_code_chrome_extension">
<link rel="apple-touch-icon" href="icons/Icon-192.png">

<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>

<title>qr_code_chrome_extension</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<!-- This script installs service_worker.js to provide PWA functionality to
application. For more information, see:
https://developers.google.com/web/fundamentals/primers/service-workers -->
<script>
var serviceWorkerVersion = null;
var scriptLoaded = false;
function loadMainDartJs() {
if (scriptLoaded) {
return;
}
scriptLoaded = true;
var scriptTag = document.createElement('script');
scriptTag.src = 'main.dart.js';
scriptTag.type = 'application/javascript';
document.body.append(scriptTag);
}

if ('serviceWorker' in navigator) {
// Service workers are supported. Use them.
window.addEventListener('load', function () {
// Wait for registration to finish before dropping the <script> tag.
// Otherwise, the browser will load the script multiple times,
// potentially different versions.
var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;
navigator.serviceWorker.register(serviceWorkerUrl)
.then((reg) => {
function waitForActivation(serviceWorker) {
serviceWorker.addEventListener('statechange', () => {
if (serviceWorker.state == 'activated') {
console.log('Installed new service worker.');
loadMainDartJs();
}
});
}
if (!reg.active && (reg.installing || reg.waiting)) {
// No active web worker and we have installed or are installing
// one for the first time. Simply wait for it to activate.
waitForActivation(reg.installing || reg.waiting);
} else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {
// When the app updates the serviceWorkerVersion changes, so we
// need to ask the service worker to update.
console.log('New service worker available.');
reg.update();
waitForActivation(reg.installing);
} else {
// Existing service worker is still good.
console.log('Loading app from service worker.');
loadMainDartJs();
}
});

// If service worker doesn't succeed in a reasonable amount of time,
// fallback to plaint <script> tag.
setTimeout(() => {
if (!scriptLoaded) {
console.warn(
'Failed to load app from service worker. Falling back to plain <script> tag.',
);
loadMainDartJs();
}
}, 4000);
});
} else {
// Service workers not supported. Just drop the <script> tag.
loadMainDartJs();
}
</script>
</body>
</html>

Kemudian, kita ubah bagian tag script -nya menjadi seperti berikut.

<!DOCTYPE html>
<html>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.

The path provided below has to start and end with a slash "/" in order for
it to work correctly.

For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base

This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`.
-->
<base href="$FLUTTER_BASE_HREF">

<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="QR code tools for chrome extension">

<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="qr_code_chrome_extension">
<link rel="apple-touch-icon" href="icons/Icon-192.png">

<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>

<title>qr_code_chrome_extension</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<!-- This script installs service_worker.js to provide PWA functionality to
application. For more information, see:
https://developers.google.com/web/fundamentals/primers/service-workers -->
<script src="main.dart.js" type="application/javascript"></script>
</body>
</html>

Lalu, kita perlu atur size window dari extension yang akan kita buat. Caranya, kita perlu tambahkan style di bagian tag html -nya menjadi seperti berikut.

<html style="height: 300px; width: 300px">

Sekarang kita coba build flutter web-nya menggunakan perintah berikut.

flutter build web --web-renderer html --csp

Setelah berhasil ter-build. Coba kita buka Google Chrome. Kemudian, buka chrome://extensions.

Halaman manage extensions

Pilih Load unpacked dan pilih directory build/web hasil dari perintah build diatas. Jika berhasil pada tahap-tahap sebelumnya maka, aplikasi yang kita build tadi seharusnya akan tampil.

Aplikasi Flutter yang di-build tadi

Sekarang coba kita buka aplikasi extension-nya maka, tampil programnya seperti berikut.

Yeay… Proses pembuatan chrome extension-nya sudah berhasil

Buat fitur QR kode

Nah, jika proses pembuatan extension-nya sudah berhasil. Maka, langkah berikutnya adalah kita tinggal buat fitur QR kode-nya aja nih.

Untuk membuat fitur tersebut kita perlu menggunakan plugin berikut ini.

Untuk menambahkan plugin tersebut kedalam projek silakan gunakan perintah berikut ini ya.

flutter pub add qr_flutter

Tunggu beberapa saat sampai proses download plugin-nya selesai. Jika proses tersebut berhasil seharusnya didalam file pubspec.yaml kita akan menemukan bahwa plugin qr_flutter sudah ditambahkan.

Plugin qr_flutter berhasil ditambahkan

Nah, langkah berikutnya kita akan membuat tampilan utamanya ya. Untuk membuatnya silakan buka file main.dart dan ubah kode didalamnya menjadi seperti berikut.

import 'package:flutter/material.dart';
import 'package:qr_flutter/qr_flutter.dart';

void main() => runApp(const App());

class App extends StatelessWidget {
const App({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomePage(),
);
}
}

class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);

@override
State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
final controllerText = TextEditingController();
final valueNotifierQr = ValueNotifier('');
final formKey = GlobalKey<FormState>();

@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Form(
key: formKey,
child: TextFormField(
controller: controllerText,
decoration: const InputDecoration(
isDense: true,
hintText: 'Enter a text or URL',
),
maxLines: 1,
minLines: 1,
onFieldSubmitted: (value) {
// TODO: Buat fitur membuat QR kode
},
),
),
const SizedBox(height: 16),
SizedBox(
width: double.infinity,
height: 36,
child: ElevatedButton(
onPressed: () {
// TODO: Buat fitur membuat QR kode
},
child: const Text('Create QR'),
),
),
const SizedBox(height: 16),
ValueListenableBuilder(
valueListenable: valueNotifierQr,
builder: (BuildContext context, String value, _) {
return QrImage(
data: value,
version: QrVersions.auto,
size: 180,
);
},
),
],
),
),
);
}
}

Sekarang coba kita jalankan terlebih dahulu aplikasinya ya. Biar kelihatan tampilannya gimana.

flutter run -d chrome
Tampilan utamanya

Jika tampilannya sudah selesai maka, langkah berikutnya adalah kita tinggal buat fungsi untuk membuat QR kode dari teks yang diinput oleh si user. Silakan kita buka kembali file main.dart dan buat function berikut.

void doCreateQrCode() {
if (formKey.currentState!.validate()) {
final qrData = controllerText.text.trim();
valueNotifierQr.value = qrData;
}
}

Lalu, kita ubah kode todo berikut ini.

// TODO: Buat fitur membuat QR kode

Menjadi seperti ini.

doCreateQrCode();

Kemudian, coba kita jalankan lagi programnya dan tes apakah fungsi buat QR kode sudah berhasil atau tidak.

Sekarang coba kita build ulang extension-nya ya.

flutter build web --web-renderer --csp

Lalu, kita reload extension di Google chrome-nya dengan cara tekan tombol seperti yang ada di gambar berikut.

Reload qr_code_chrome_extension

Sekarang coba kita tes fitur QR kode di Google Chrome extension-nya.

Yeay… It’s working

Sekarang coba saya tes apakah QR kode-nya sudah sesuai atau belum ya menggunakan aplikasi QR code scanner di HP.

Kode QR bisa dibaca datanya

Kesimpulan

Jadi kesimpulannya adalah bahwa Flutter web sudah bisa membuat extension untuk Google Chrome. Dan ini merupakan tanda bahwa Flutter benar-benar serius dikembangkan untuk web. Dan mudah-mudahan saja Flutter web bisa ikut berpartisipasi dalam daftar web framework yang ada.

--

--

Stories and insights from the developers in Nusanet

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store