Flutter Lesson 27 of 83 3 min read
Assets and Custom Fonts in Flutter
Add images, JSON files and custom fonts to a Flutter app: declare them in pubspec.yaml, load them in code and use Google Fonts.
On this page
An asset is a file shipped inside your app: images, fonts, JSON data, audio. Assets are available offline and load instantly.
Declaring assets #
Create a folder at the project root and list it in pubspec.yaml.
my_app/
assets/
images/
logo.png
banner.jpg
data/
cities.json
fonts/
Poppins-Regular.ttf
Poppins-SemiBold.ttf
lib/
pubspec.yaml
flutter:
uses-material-design: true
assets:
- assets/images/ # every file directly in this folder
- assets/data/cities.json # one specific file
A path ending in / includes the files in that folder, but not its sub-folders. List each sub-folder separately.
Using an image asset #
Image.asset('assets/images/logo.png', width: 120)
The usual reasons an asset is “not found” #
- Wrong indentation in
pubspec.yaml.assets:must be indented underflutter:, by two spaces. - A typo, or different upper and lower case, in the path.
- The app was only hot reloaded. After changing
pubspec.yaml, stop and run again. - The file is in a sub-folder that was not listed.
Loading text and JSON #
import 'dart:convert';
import 'package:flutter/services.dart' show rootBundle;
Future<List<String>> loadCities() async {
final text = await rootBundle.loadString('assets/data/cities.json');
final list = jsonDecode(text) as List<dynamic>;
return list.cast<String>();
}
Inside a widget, DefaultAssetBundle.of(context).loadString(...) does the same and is easier to replace in tests.
Custom fonts #
Put the font files in the project and declare a family.
flutter:
fonts:
- family: Poppins
fonts:
- asset: assets/fonts/Poppins-Regular.ttf
- asset: assets/fonts/Poppins-SemiBold.ttf
weight: 600
- asset: assets/fonts/Poppins-Italic.ttf
style: italic
Use it for the whole app:
MaterialApp(
theme: ThemeData(
fontFamily: 'Poppins',
colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
),
home: const HomePage(),
)
Or for one piece of text:
const Text('Hello', style: TextStyle(fontFamily: 'Poppins', fontWeight: FontWeight.w600))
Declare a file for every weight you use. If you ask for w600 and only the regular file exists, Flutter fakes the bold, and it looks poor.
Google Fonts #
The google_fonts package gives access to the whole Google Fonts library without managing files.
flutter pub add google_fonts
import 'package:google_fonts/google_fonts.dart';
MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
textTheme: GoogleFonts.interTextTheme(),
),
home: const HomePage(),
)
Text('Title', style: GoogleFonts.playfairDisplay(fontSize: 32))
By default the fonts are downloaded the first time they are needed. For a released app, download the files and bundle them as assets, so text looks right even on the first, offline launch.
Icons from a font #
Material icons are included when uses-material-design: true is set. For other icon sets, use a package such as font_awesome_flutter, or generate an icon font from your own SVGs.
Avoiding typos in paths #
A wrong path fails only when the app runs. Keep the strings in one place:
abstract final class Assets {
static const logo = 'assets/images/logo.png';
static const banner = 'assets/images/banner.jpg';
static const cities = 'assets/data/cities.json';
}
Image.asset(Assets.logo)
The flutter_gen package can generate such a class from your pubspec.yaml.
App size #
Everything in assets adds to the download size.
- Compress images. Use WebP for photos.
- Do not ship fonts or weights you do not use.
- Load large or rarely used media from the network.
Try it yourself #
Add a logo image and a custom font to a project. Show the logo on the home page, apply the font to the whole app, and load a small JSON file of quotes from assets to display one at random.