I am trying to add my company's logo to an R shiny app, made using {bslib}. I tried different ways of adding this image to the 'title' argument of 'page_navbar'. While the image gets added, it looks wonky and changes the position of the other items in the header ribbon. An example image and the logo attached.
Here is a demo code that illustrates the problem:
library(shiny)
library(bslib)
ui <- page_navbar(
title = div("My app",
img(src = "WCTMainLogoWhite_edited.png", height = "57.5px", width = "auto",
style = "position: absolute;
top: 1px;
right: 2%;")),
theme = bs_theme(version = 5, bootswatch = "zephyr")|> ##setting the primary color of "zephyr" bootswatch theme manually
bslib::bs_add_rules(
rules = "
.navbar.navbar-default {
background-color: $primary !important;
}
"
),
nav_panel(title = "Trends",
layout_columns(
card(
full_screen = TRUE,
card_header(
"Card 1")
)),
layout_columns(
card(
full_screen = TRUE,
card_header("Card 2")),
card(
full_screen = TRUE,
card_header("Card 3")),
col_widths = c(12, 12)
)
),
nav_panel(title = "Instructions on use", p("Content to be added"))
)
server <- function(input, output, session) {}
shinyApp(ui, server)
Is there a better way to add the image, that will align with the other items in the header?
Discussed are the cases of a right-aligned logo (similar to your example) and a left-aligned one separately.
I would use an approach as given in this answer, the image is just appended to the navbar
. In the below example, we calculate and provide the height dynamically based on the container height (such that the navbar
does not get blown up), but it is possible to modify this.
To consider is also the case if one is below the lg breakpoint (or another one if one does not use the default). This does not lead to a satisfactory result because then the navbar
gets collapsed and the image position changes. In my opinion, the best style is to hide a right-aligned logo in a collapsed navbar
. This in particular lets space for the hamburger button. Therefore I implemented @media (max-width:992px)
css which applies display: none;
. It is of course also possible to modify this if you want to keep the image.
library(shiny)
library(bslib)
ui <- page_navbar(
title = "Logo example",
theme = bs_theme(5, "zephyr"),
navbar_options = list(class = "bg-primary", theme = "dark"),
nav_panel(
title = "Nav panel title",
tags$head(
tags$script(
HTML('
$(document).ready(function() {
var containerHeight = $(".navbar .container-fluid").height() + "px";
$(".navbar .container-fluid")
.append(
"<img id = \'myImage\' src=\'WCTMainLogoWhite_edited.png\'" +
" align=\'right\' height = " + containerHeight + ">"
);
});'
)
),
tags$style(
HTML('@media (max-width:992px) { #myImage { display: none; }}')
)
)
)
)
shinyApp(ui, \(...){})
Here we use an approach similar to what is described within the Bootstrap docs on Brand. Within the .navbar-brand
, we could add the image (the logo then acts as brand and we omit a specific title). However, currently bslib takes the title
argument of page_navbar()
and defines the brand as a span
containing the title. Hence, I modify the tag here such that the HTML looks like within the Bootstrap docs.
I also modify the padding because otherwise the navbar
seems to get a little bit blown up when it is collapsed.
library(shiny)
library(bslib)
ui <- page_navbar(
title = "",
theme = bs_theme(5, "zephyr"),
navbar_options = list(class = "bg-primary", theme = "dark"),
nav_panel(
title = "Nav panel title",
tags$head(
tags$script(
HTML('
$(document).ready(function() {
$(".navbar-brand").replaceWith(
$("<a class = \'navbar-brand\' href = \'#\'></a>")
);
var containerHeight = $(".navbar .container-fluid").height() + "px";
$(".navbar-brand")
.append(
"<img id = \'myImage\' src=\'WCTMainLogoWhite_edited.png\'" +
" height = " + containerHeight + ">"
);
});'
)
),
tags$style(
HTML('@media (max-width:992px) { .navbar-brand { padding-top: 0; padding-bottom: 0; }}')
)
)
)
)
shinyApp(ui, \(...){})