Search code examples
rshinybslib

How to provide a local font for a shiny app via bslib?


This works if I put inside my UI:

library(shiny)
 bslib::page_fluid(

      tags$style(HTML("@font-face {
    font-family: 'Hunger Games';
    src: url('www/Hunger Games.ttf') format('truetype');
  }"))
)

But this does not work:

library(shiny)
     bslib::page_fluid(
        theme = bs_theme(version = 5,
                       preset = "shiny",
                       heading_font = font_face(
                         family = 'Hunger Games',
                       src = "url('www/Hunger Games.ttf') format('truetype')"))
)

Solution

  • I found by using the inspector Tools. The app is looking for a file Hunger Games-0.4.7/Hunger Games.ttf, in the www subfolder. So you have to put your file Hunger Games.ttf in www/Hunger Games-0.4.7, and don't write www/ in url. The 0.4.7 is the version of the sass package.

    This does not throw a 404 error:

    thm <- bs_theme(version = 5,
             preset = "shiny",
             heading_font = font_face(
               family = 'Hunger Games',
               src = "url('Hunger Games.ttf') format('truetype')"))
    bs_theme_preview(thm)
    

    EDIT

    The above does not work in Shiny (or does not work at all, not sure...).

    Now I've found how to do with Shiny. You have to add a resource path, for example you create a fonts subfolder in which you put the ttf file, and you use the addResourcePath function. This function requires a prefix, I take fonts in the example below. Then you have to prefix the ttf file in url, like this: url('/myprefix/myfontfile.ttf').

    library(bslib)
    library(shiny)
    
    addResourcePath("fonts", "./fonts") # the first 'fonts' is the prefix
    
    thm <- bs_theme(
      version = 5,
      preset = "shiny",
      heading_font = font_face(
        family = "HungerGames",
        src = "url('/fonts/HungerGames.ttf') format('truetype')"
      )
    )
    
    ui <- page_fluid(
      theme = thm,
      title = "Hello",
      tags$h1("Test")
    )
    
    shinyApp(ui, function(input, output){})
    

    (Note that I removed the white space in your font file name, because I feared it could cause another difficulty; I didn't try with the white space.)