How To Download Files With The web Package In Flutter Apps

Flutter category image

Introduction

Since the release of Dart 3.7, your Flutter web app will give you warnings when you use dart:html in your code and have the latest Dart version activated. It was deprecated by the Flutter team. In this article, I am going to show you how to download files with the web package in Flutter apps. To do that, we will remove dart:html, replace it with the web package, and apply some code changes.

Here is more information about what was deprecated and here is a migration guide about refactoring dart:html.

The use case

You have a Flutter web app and want to give your users the ability to download text files like CSV that are created on the fly.

Let’s assume, your app tracks the daily steps of a user. They can download monthly summaries with steps per day. This is a good example for a CSV file and can be easily used by other apps like Google Docs or Microsoft Office.

Here is how to download files with the web package in Flutter apps and fix the warnings from the Dart analyzer.

The old way

You probably have a dart:html import like this in your code.

Dart
import 'dart:convert';
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;

And you also have a download function to trigger a browser download like the one below. We assume here that csv already contains the prepared content.

Dart
Future _download(String csv, String fileName) async {
  final bytes = utf8.encode(csv);
  final blob = html.Blob([bytes]);
  final url = html.Url.createObjectUrlFromBlob(blob);
  final anchor = html.document.createElement('a') as html.AnchorElement
    ..href = url
    ..style.display = 'none'
    ..download = '$fileName.csv';

  html.document.body!.children.add(anchor); 
  anchor.click(); 

  html.document.body!.children.remove(anchor);
  html.Url.revokeObjectUrl(url);
}

This is what most AIs will propose to you at the moment when you ask them how such a download can be achieved. It still works but any future version could drop support for this piece of code.

The new way

Instead of dart:html, the new way is to use the web package. The obvious first step is to install it with this command:

Bash
flutter pub add web

Then, we focus on the _download() function. Here is the updated version:

Dart
Future _download(String csv, String fileName) async {
  final blob = Blob(JSArray.from(utf8.encode(csv).toJS));
  final url = URL.createObjectURL(blob);

  final anchor =
      HTMLAnchorElement()
        ..href = url
        ..download = '$fileName.csv';

  document.body?.append(anchor);
  anchor.click();
  anchor.remove();

  URL.revokeObjectURL(url);
}

We replaced all references to the old dart:html package. The call toJS is a little tricky and it took me a while to figure it out until the compiler stopped complaining.

To round things up, we update the import section as follows:

Dart
import 'dart:js_interop';
import 'package:web/web.dart';

With that, your function should work again and not produce any more deprecation warnings!

Conclusion

With Dart 3.7, you need to make some changes to your code and move away from dart:html. In this article I showed you how to do that on a common example. Removing deprecated code parts is always recommended to make your code ready for the future.


Want More Flutter Content?

Join my bi-weekly newsletter that delivers small Flutter portions right in your inbox. A title, an abstract, a link, and you decide if you want to dive in!

Flutter ❤️ Firebase

Get started with Firebase and learn how to use it in your Flutter apps. My detailed ebook delivers you everything you need to know! Flutter and Firebase are a perfect match!

Become A Testing Expert!

Become a proficient Flutter app tester with my detailed guide. This ebook covers everything from unit tests over widget tests up to dependency mocking.