0

I'm building a Flutter Web app and I need to avoid loading fonts from any external CDN (company policy / privacy reasons).

Instead, I want to bundle all fonts locally and have Flutter use only those.

However, even after adding my own fonts to pubspec.yaml and updating my ThemeData, the app still tries to load fonts from a CDN (e.g.
https://fonts.gstatic.com/s/notocoloremoji/v32/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.3.woff2 or a similar font CDN). I either want to completely block this or configure Flutter so it does not attempt to use the CDN at all.

What I’m doing now:

I’m using Flutter (Web) with a custom font.

Here is my pubspec.yaml regarding fonts:

flutter:
 generate: true
 uses-material-design: false
 assets:
 - assets/logos/
 - assets/icons/
 - assets/fonts/
 fonts:
 - family: Roboto
 fonts:
 - asset: assets/fonts/Roboto-Light.ttf
 - asset: assets/fonts/Roboto-Medium.ttf
 - asset: assets/fonts/Roboto-Regular.ttf
 - asset: assets/fonts/Roboto-Italic.ttf
 - asset: assets/fonts/Roboto-Bold.ttf
 - family: NotoSansSymbols
 fonts:
 - asset: assets/fonts/NotoSansSymbols-Regular.ttf
 - family: NotoSansSymbols2
 fonts:
 - asset: assets/fonts/NotoSansSymbols2-Regular.ttf
 - family: LocalNotoColorEmoji
 fonts:
 - asset: assets/fonts/NotoColorEmoji-Regular.ttf
 - family: Font Awesome 7 Pro
 fonts:
 - asset: assets/icons/Font Awesome 7 Pro-Light-300.otf
 weight: 300

In my theme.dart I set my fonts like this:

class AppTheme {
 AppTheme._();
 // light theme
 static ThemeData lightTheme = ThemeData(
 useMaterial3: true,
 brightness: Brightness.light,
 primaryColor: CustomColors.primary,
 scaffoldBackgroundColor: CustomColors.primaryBackground,
 canvasColor: CustomColors.primaryBackground,
 fontFamily: 'Roboto',
 textTheme: CustomTextTheme.lightTextTheme.apply(
 fontFamily: 'Roboto',
 fontFamilyFallback: [
 'NotoSansSymbols',
 'NotoSansSymbols2',
 'LocalNotoColorEmoji',
 'Apple Color Emoji', // macOS / iOS
 'Segoe UI Emoji', // Windows
 'Noto Color Emoji', // Linux / Android
 'EmojiOne Color', // Linux / Firefox
 ],
 ),

I do not explicitly use the google_fonts package anywhere.

When I open the app in the browser, I still see network requests to a font CDN in the dev tools, for example:

https://fonts.gstatic.com/s/notocoloremoji/v32/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.3.woff2

If I block those requests (e.g. via the browser dev tools or a network filter), the app still works, but I want to ensure it never tries to load these external fonts in the first place.

halfer
20.2k20 gold badges111 silver badges208 bronze badges
asked Dec 10, 2025 at 14:43

2 Answers 2

2

It looks like the --no-web-resources-cdn flag doesn't handle fonts. Issue #163554 on the GitHub repo describes it in detail, a team member interested in fixing it. It looks like you mostly implemented the work-around from Johannes Mayer fro there:

Add this to your pubspec.yaml:

fonts:
 - family: Roboto
 fonts:
 - asset: assets/fonts/Roboto-Regular.ttf
 - asset: assets/fonts/Roboto-Medium.ttf
 weight: 500
 - asset: assets/fonts/Roboto-Bold.ttf
 weight: 700

I found those fonts in a gfonts.dart via those URLs:

  • Roboto-Regular: fonts.gstatic.com/s/roboto/v32/KFOmCnqEu92Fr1Me5WZLCzYlKw.ttf
  • Roboto-Medium: fonts.gstatic.com/s/roboto/v32/KFOlCnqEu92Fr1MmEU9vAx05IsDqlA.ttf
  • Roboto-Bold: fonts.gstatic.com/s/roboto/v32/KFOlCnqEu92Fr1MmWUlvAx05IsDqlA.ttf put them into assets/fonts folder

Call flutter pub get

Not sure if needed but in lib/main.dart I also added Roboto as explicit font family:

 return MaterialApp(
 theme: ThemeData(
 fontFamily: 'Roboto', //required to stick with local Roboto
 ...

And you are good to go... Check network tab of a private browser if roboto request is now getting it from your domain instead.

The biggest difference between that and your code that I can see is that you specify fontFamilyFallback, which the link does not do. If you do indeed have to specify a fallback, it makes sense that the load first tries to load the font from the URL, and only goes for the fallback once the URL is unreachable. So I'd remove the fallback URL, and check against te above and the GitHub link to make sure you follow the exact same process.

If you can't get it to work without the fallback, you could consider implementing the other workaround by GiovanniRaseraF (cetriolino).

answered Dec 10, 2025 at 15:05
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! The workaround from Giovanni did work, but I find it quite awkward that there is no easier way to restrict cdn's in Flutter :(
That's why I pointed out that a Flutter team engineer chimed in too. Hopefully they'll work to change this behavior, but prioritization if fickle. So if you can't wait for that, you can of course always submit a PR with a fix.
0

Coincidentally I am referred in Frank van Puffelen's Post. I am revisiting this topic because on one screen my network tab still tried to fetch two fonts. NotoSansSymbols as well as NotoColorEmoji.

Turns out reason was we used an inline success emoji on that screen which triggered flutter to internally download fonts.

So for me the solution was to replace the celebration emoji with Icons.celebration. Also commonly you can choose cupertino_icons or font_awesome_flutter (you can also download SVGs from their website) packages.

answered Dec 15, 2025 at 14:30

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.