R包inst文件夹内字体路径错误致Shiny应用无法加载字体的问题
问题描述
我正在开发一款可在Markdown/Shiny报告中复用的R包,通过自定义fonts()函数将<h1>标题和<p>文本设置为Clarke Regular与Clarke Black字体,字体文件已上传至包的inst文件夹。但从GitHub下载包后,在简单的Hello World Shiny应用中调用fonts()函数时,字体无法加载!请问是否是字体文件路径存在问题?应如何调用inst文件夹中的字体文件?
现有代码
#' Add together two numbers #' @importFrom shiny tags #' @export fonts #' fonts <- function(){ shiny::tags$style( HTML(paste0(" @font-face { src: url('", system.file("Clarke-Regular.otf", package = "XXThemes"), "'); font-family: 'Clarke-Regular'; } @font-face { src: url('", system.file("Clarke-Black.otf", package = "XXThemes"), "'); font-family: 'Clarke-Black'; } /* Body Colors and Background for Template */ /* ++++++++++++++++++++++++++++++++++++++++++++++++ */ body { font-family: 'Clarke-Regular'; } h1 { font-family: 'Clarke-Black'; font-size: 48px; } p { font-family: 'Clarke-Regular'; color: #000000; } ul { font-family: 'Clarke-Regular'; } b, strong { font-weight: bold; } ") ) ) }
问题分析与解决方案
核心问题
system.file()返回的是本地文件系统的绝对路径,但Shiny是网页应用,浏览器没有权限访问本地文件路径,这直接导致字体加载失败。
解决步骤
1. 调整字体文件存放路径
在包的inst目录下新建www/fonts子文件夹,将Clarke-Regular.otf和Clarke-Black.otf移动到该目录下。包安装完成后,这些文件会被自动复制到包的www/fonts目录中,成为Shiny可访问的资源。
2. 注册Shiny资源路径
在包的zzz.R文件(若无则新建)中添加包加载时的资源注册逻辑,让Shiny能识别字体资源的路径:
.onLoad <- function(libname, pkgname) { shiny::addResourcePath("xxthemes_fonts", system.file("www/fonts", package = pkgname)) }
3. 修改fonts()函数
移除system.file()的使用,改用注册好的资源路径,同时优化字体加载逻辑:
#' 自定义字体样式 #' @importFrom shiny tags HTML #' @export fonts #' fonts <- function(){ shiny::tags$style( shiny::HTML(" @font-face { src: url('xxthemes_fonts/Clarke-Regular.otf'); font-family: 'Clarke-Regular'; font-display: swap; /* 优化字体加载体验 */ } @font-face { src: url('xxthemes_fonts/Clarke-Black.otf'); font-family: 'Clarke-Black'; font-display: swap; } /* Body Colors and Background for Template */ body { font-family: 'Clarke-Regular', sans-serif; /* 添加 fallback 字体 */ } h1 { font-family: 'Clarke-Black', sans-serif; font-size: 48px; } p { font-family: 'Clarke-Regular', sans-serif; color: #000000; } ul { font-family: 'Clarke-Regular', sans-serif; } b, strong { font-weight: bold; } ") ) }
4. 验证与测试
- 重新安装包后,用
system.file("www/fonts/Clarke-Regular.otf", package = "XXThemes")检查路径是否存在 - 在Shiny应用中调用
XXThemes::fonts(),确认字体正常加载
内容的提问来源于stack exchange,提问作者Dieu94
相关产品推荐
相关产品推荐

