{"id":32302260,"url":"https://github.com/sidrao2006/dynamic_cached_fonts","last_synced_at":"2025-10-23T05:56:14.434Z","repository":{"id":36979761,"uuid":"315196998","full_name":"sidrao2006/dynamic_cached_fonts","owner":"sidrao2006","description":"A font loader to download, cache and load web fonts in flutter with support for Firebase Cloud Storage.","archived":false,"fork":false,"pushed_at":"2024-11-28T07:03:51.000Z","size":13914,"stargazers_count":28,"open_issues_count":7,"forks_count":26,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-23T05:56:13.545Z","etag":null,"topics":["cache","firebase-cloud-storage","flutter","flutter-package","font","optimization","pub","web-fonts"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/dynamic_cached_fonts","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sidrao2006.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-11-23T04:08:11.000Z","updated_at":"2025-10-20T09:54:49.000Z","dependencies_parsed_at":"2024-06-01T21:30:30.425Z","dependency_job_id":"48d25b0d-8405-442f-994d-529a5655b75c","html_url":"https://github.com/sidrao2006/dynamic_cached_fonts","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/sidrao2006/dynamic_cached_fonts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidrao2006%2Fdynamic_cached_fonts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidrao2006%2Fdynamic_cached_fonts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidrao2006%2Fdynamic_cached_fonts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidrao2006%2Fdynamic_cached_fonts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sidrao2006","download_url":"https://codeload.github.com/sidrao2006/dynamic_cached_fonts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sidrao2006%2Fdynamic_cached_fonts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280569896,"owners_count":26352860,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-23T02:00:06.710Z","response_time":142,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cache","firebase-cloud-storage","flutter","flutter-package","font","optimization","pub","web-fonts"],"created_at":"2025-10-23T05:56:08.964Z","updated_at":"2025-10-23T05:56:14.425Z","avatar_url":"https://github.com/sidrao2006.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dynamic Cached Fonts\n\n[![Pub Version][pub-version-badge]][pub-package]\n![Supported Platforms][supported-platforms-badge]\n\n\u003c!-- CI badges --\u003e\n[![Unit Tests][unit-tests-badge]][unit-tests]\n[![Integration Tests][integration-tests-badge]][integration-tests]\n\nA simple, easy to use yet customizable font loader to use web fonts.\n\nDemo: https://sidrao2006.github.io/dynamic_cached_fonts\n\n![Demo 3]\n\n## 👋 Introduction\n\nDynamic Cached Fonts allows you to dynamically load a font from any url and cache it. This way, you can reduce your bundle size and load the font if and when it's required.\n\nAnother advantage of dynamically loading fonts is that you can now easily provide an option to your users to pick an app font. This allows for a greater level of customization.\n\nCaching is an added performance upgrade as the font will be downloaded only once and used multiple times, reducing network and battery usage.\n\n## 🏃 Get Started\n\nTo use the package, add `dynamic_cached_fonts` as a [dependency][install].\n\n## ⚒️ Usage\n\n### Loading fonts on demand\n\nYou can load font on demand, for example - when a page loads\n\n```dart\n@override\nvoid initState() {\n  final DynamicCachedFonts dynamicCachedFont = DynamicCachedFonts(\n    fontFamily: fontFamilyName, // The font family name to be passed to TextStyle.fontFamily\n    url: fontUrl, // A valid url pointing to a font file (.ttf or .otf files only) \n  );\n  dynamicCachedFont.load(); // Downloads the font, caches and loads it.\n\n  super.initState();\n}\n...\nText(\n  'Some Text',\n  style: TextStyle(fontFamily: fontFamilyName),\n)\n```\n\n![Demo 1]\n\nOr when a button is clicked\n\n```dart\nElevatedButton(\n  onPressed: () {\n    final DynamicCachedFonts dynamicCachedFont = DynamicCachedFonts(\n      fontFamily: fontFamilyName,\n      url: fontUrl,\n    );\n\n    dynamicCachedFont.load();\n  },\n  child: const Text('Load Font'),\n),\n```\n\n![Demo 2]\n\nIf you want to change how large the cache can be or maybe how long the font stays in cache, pass in `maxCacheObjects` and `cacheStalePeriod`.\n\n```dart\nDynamicCachedFonts(\n  fontFamily: fontFamilyName,\n  url: fontUrl,\n  maxCacheObjects: 150,\n  cacheStalePeriod: const Duration(days: 100),\n);\n```\n\n`TextStyle.fontFamily`s are applied only after `load()` is called.\n\n\u003e Calling `load()` more than once throws a `StateError`\n\nWhat if you need to load multiple fonts, of varying weights and styles, as a single family...For that, you can use the `DynamicCachedFonts.family` constructor.\n\nIt accepts a list of urls, pointing to different fonts in the same family, as `urls`.\n\n```dart\nDynamicCachedFonts.family(\n  urls: \u003cString\u003e[\n    fontFamilyNameBoldUrl,\n    fontFamilyNameItalicUrl,\n    fontFamilyNameRegularUrl,\n    fontFamilyNameThinUrl,\n  ],\n  fontFamily: fontFamilyName,\n);\n```\n\n![Demo 5]\n\nThe package also supports loading the fonts as a `Stream`! The `loadStream` returns a **single subscription stream** which emits the font files.\n\n`loadStream` accepts a callback, `downloadProgressListener`, that is called each time a `DownloadProgress` event is received. This happens only when the font is actually being downloaded from the provided url. Subsequent requests, which are usually served from the cache, do not emit any progress events. If the font file has expired, then the file will be downloaded again for which the progress events will be streamed to `downloadProgressListener`.\n\nWhen `loadStream` is called with a single font url, then `itemCountProgressListener` will be called only once when the font has been loaded into the engine.\n\n```dart\nfinal DynamicCachedFonts dynamicCachedFont = DynamicCachedFonts(\n  fontFamily: fontFamilyName,\n  url: fontUrl,\n);\n\ndynamicCachedFont.loadStream(\n  itemCountProgressListener: (double progress, int totalItems, int downloadedItems) {},\n  downloadProgressListener: (DownloadProgress progress) {},\n);\n```\n\nAnd when `loadStream` is used to load an entire font family, `itemCountProgressListener` will be called once for every font in the family.\nIn the example given below, `itemCountProgressListener` will be called 4 times, once after every font has been loaded into the Flutter engine.\n\n```dart\nfinal DynamicCachedFonts dynamicCachedFont = DynamicCachedFonts.family(\n  urls: \u003cString\u003e[\n    fontFamilyNameBoldUrl,\n    fontFamilyNameItalicUrl,\n    fontFamilyNameRegularUrl,\n    fontFamilyNameThinUrl,\n  ],\n  fontFamily: fontFamilyName,\n);\n\ndynamicCachedFont.loadStream(\n  itemCountProgressListener: (double progress, int totalItems, int downloadedItems) {},\n  downloadProgressListener: (DownloadProgress progress) {},\n);\n```\n\n\u003e Calling `loadStream` more than once throws a `StateError`\n\n![Demo 6]\n\nIf you need more control, use the static methods!\n\n#### `cacheFont`\n\n```dart\nonPressed: () {\n  DynamicCachedFonts.cacheFont(fontUrl);\n},\nchild: const Text('Download font'),\n```\n\nYou can pass in `maxCacheObjects` and `cacheStalePeriod` here as well.\n\n#### `canLoadFont`, `loadCachedFont`, `loadCachedFamily`\n\n`canLoadFont` is used to check whether the font is available in cache. It is usually used in combination with the `loadCached*` methods.\n\nFirst, Check whether the font is already in cache. If it is, then load the font.\n\n\n```dart\nif(DynamicCachedFonts.canLoadFont(fontUrl)) {\n  // To load a single font...\n  DynamicCachedFonts.loadCachedFont(\n    fontUrl,\n    fontFamily: fontFamilyName,\n  );\n\n  // Or if you want to load multiple fonts as a family...\n  DynamicCachedFonts.loadCachedFamily(\n    \u003cString\u003e[\n      fontFamilyNameBoldUrl,\n      fontFamilyNameItalicUrl,\n      fontFamilyNameRegularUrl,\n      fontFamilyNameThinUrl,\n    ],\n    fontFamily: fontFamilyName,\n  );\n}\n```\n\nNow, if the font isn't available in cache, download it!\n\n```dart\nif(DynamicCachedFonts.canLoadFont(fontUrl)) {\n  ...\n} else {\n  DynamicCachedFonts.cacheFont(fontUrl);\n}\n```\n\n#### `cacheFontStream`\n\n`cacheFontStream` is used to download and cache the font. This method is similar to `cacheFont` but returns a **single subscription `Stream`** that emits the progress of the download.\nThe download is streamed to the `progressListener` callback which is called each time a `DownloadProgress` event is received. This happens only when the font is actually being downloaded from the provided url. Subsequent requests, which are usually served from the cache, do not emit any progress events. If the font file has expired, then the file will be downloaded again for which the progress events will be streamed to `downloadProgressListener`.\n\n```dart\nDynamicCachedFonts.cacheFontStream(\n  fontUrl,\n  progressListener: (DownloadProgress progress) {},\n);\n```\n\n#### `loadCachedFamilyStream`\n\nUse `canLoadFont` to check whether the font is available in cache.\n\n`loadCachedFamilyStream` is used to load multiple fonts into the Flutter engine, as a single font family. This method is similar to `loadCachedFamily` but returns a stream.\n\nWhen `loadCachedFamilyStream` is called with a single font url, `progressListener` will be called only once when the font has been loaded into the engine.\n\nAnd when `loadCachedFamilyStream` is used to load an entire font family, `progressListener` will be called once for every font in the family.\nIn the example given below, `progressListener` will be called 4 times, once after every font has been loaded into the Flutter engine.\n\n```dart\nDynamicCachedFonts.loadCachedFamilyStream(\n  \u003cString\u003e[\n    fontFamilyNameBoldUrl,\n    fontFamilyNameItalicUrl,\n    fontFamilyNameRegularUrl,\n    fontFamilyNameThinUrl,\n  ],\n  fontFamily: fontFamilyName,\n  progressListener: (double progress, int totalItems, int downloadedItems) {},\n);\n```\n\n![Demo 7]\n\n#### `removeCachedFont`\n\nTo remove a font from cache **permanently**, use `removeCachedFont`.\n\n\u003e Note - This does not change the font immediately until a complete app restart.\n\n![Demo 3]\n\nFinally, if you want to customize their implementation, extend `RawDynamicCachedFonts` and override the static methods.\n\nHave a custom font to load from Firebase Cloud Storage? Go for the `DynamicCachedFonts.fromFirebase` constructor! It accepts a Google Cloud Storage location which is a url starting with `gs://`. Other than that, it is similar to the default constructor.\n\n\u003e Tip: Use `DynamicCachedFonts.toggleVerboseLogging` to log detailed statuses and configurations for debugging.\n\n![Demo 4]\n\n## 🐛 Bug Reports and Help\n\nIf you find a bug, please open an issue on [Github][issue_tracker] or if you need any help, let's discuss on [Github Discussions]!\n\n## 💁 Contributing\n\nTo make things easier, you can use [docker compose] to set up a dev environment.\nJust run `docker compose run linux` to set up a Linux dev environment or run `docker compose run windows` to set up a Linux dev environment.\n\n\u003e You need to be on a Windows machine to be able to set up a docker Windows environment.\n\nTo contribute to the package, fork the repository and open a [pull request]!\n\n[![GitHub Forks][github-forks-badge]][github-forks]\n[![Github Stars][github-stars-badge]][github-stars]\n\n\u003c!-- Badges --\u003e\n[supported-platforms-badge]: https://img.shields.io/badge/Platforms-Android%20%7C%20iOS%20%7C%20Web%20%7C%20Windows%20%7C%20Linux%20%7C%20MacOS-blue?style=for-the-badge\n[pub-version-badge]: https://img.shields.io/pub/v/dynamic_cached_fonts?label=Pub%20%28Latest%20Stable%29\u0026style=for-the-badge\n[unit-tests-badge]:https://github.com/sidrao2006/dynamic_cached_fonts/actions/workflows/package_unit_test.yml/badge.svg\n[integration-tests-badge]: https://github.com/sidrao2006/dynamic_cached_fonts/actions/workflows/integration_test.yml/badge.svg\n[github-forks-badge]: https://img.shields.io/github/forks/sidrao2006/dynamic_cached_fonts?style=social\n[github-stars-badge]: https://img.shields.io/github/stars/sidrao2006/dynamic_cached_fonts?style=social\n\n\u003c!-- Badge Follow Up Links --\u003e\n[pub-package]: https://pub.dev/packages/dynamic_cached_fonts\n[unit-tests]:https://github.com/sidrao2006/dynamic_cached_fonts/actions/workflows/package_unit_test.yml\n[integration-tests]: https://github.com/sidrao2006/dynamic_cached_fonts/actions/workflows/integration_test.yml\n[github-forks]: https://github.com/sidrao2006/dynamic_cached_fonts/fork\n[github-stars]: https://github.com/sidrao2006/dynamic_cached_fonts\n\n\u003c!-- GIFs --\u003e\n[Demo 1]: https://raw.githubusercontent.com/sidrao2006/dynamic_cached_fonts/main/doc/images/demo1.gif\n[Demo 2]: https://raw.githubusercontent.com/sidrao2006/dynamic_cached_fonts/main/doc/images/demo2.gif\n[Demo 3]: https://raw.githubusercontent.com/sidrao2006/dynamic_cached_fonts/main/doc/images/demo3.gif\n[Demo 4]: https://raw.githubusercontent.com/sidrao2006/dynamic_cached_fonts/main/doc/images/demo4.gif\n[Demo 5]: https://raw.githubusercontent.com/sidrao2006/dynamic_cached_fonts/main/doc/images/demo5.gif\n[Demo 6]: https://raw.githubusercontent.com/sidrao2006/dynamic_cached_fonts/main/doc/images/demo6.gif\n[Demo 7]: https://raw.githubusercontent.com/sidrao2006/dynamic_cached_fonts/main/doc/images/demo7.gif\n\n[install]: https://pub.dev/packages/dynamic_cached_fonts/install\n[issue_tracker]: https://github.com/sidrao2006/dynamic_cached_fonts/issues/new/choose\n[Github Discussions]: https://github.com/sidrao2006/dynamic_cached_fonts/discussions/new?category=q-a\n[docker compose]: https://docs.docker.com/compose/\n[pull request]: https://github.com/sidrao2006/dynamic_cached_fonts/compare/main\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsidrao2006%2Fdynamic_cached_fonts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsidrao2006%2Fdynamic_cached_fonts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsidrao2006%2Fdynamic_cached_fonts/lists"}