Skip to contents

This vignette goes deep into content collections - the first layer of dashboardr’s architecture. For a quick overview, see vignette("getting-started").

Throughout this vignette, we use the General Social Survey as example data. Click below to see the data loading code.

πŸ“‚ Data Setup (click to expand)
library(dashboardr)
library(dplyr)
library(gssr)
library(haven)

# Load GSS data
data(gss_all)

# Latest wave only (for most examples)
gss <- gss_all %>%
  select(year, age, sex, race, degree, happy, polviews, wtssps,
         # Continuous variables for scatter plots
         educ, childs,
         # Confidence in institutions (for multi-question stackedbar example)
         confinan, conbus, coneduc, confed, conmedic) %>%
  filter(year == max(year, na.rm = TRUE)) %>%
  # Filter to substantive responses for core variables
  filter(
    happy %in% 1:3,        # very happy, pretty happy, not too happy
    polviews %in% 1:7,     # extremely liberal to extremely conservative
    !is.na(age), !is.na(sex), !is.na(race), !is.na(degree)
  ) %>%
  # Convert to factors with proper labels
  mutate(
    happy = droplevels(as_factor(happy)),
    polviews = droplevels(as_factor(polviews)),
    degree = droplevels(as_factor(degree)),
    sex = droplevels(as_factor(sex)),
    race = droplevels(as_factor(race)),
    # Confidence variables: convert non-substantive (IAP, don't know, etc.) to NA
    # Then use drop_na_vars = TRUE in visualizations
    confinan = ifelse(confinan %in% 1:3, confinan, NA),
    conbus = ifelse(conbus %in% 1:3, conbus, NA),
    coneduc = ifelse(coneduc %in% 1:3, coneduc, NA),
    confed = ifelse(confed %in% 1:3, confed, NA),
    conmedic = ifelse(conmedic %in% 1:3, conmedic, NA),
    # Convert to labeled factors
    confinan = factor(confinan, levels = 1:3, labels = c("a great deal", "only some", "hardly any")),
    conbus = factor(conbus, levels = 1:3, labels = c("a great deal", "only some", "hardly any")),
    coneduc = factor(coneduc, levels = 1:3, labels = c("a great deal", "only some", "hardly any")),
    confed = factor(confed, levels = 1:3, labels = c("a great deal", "only some", "hardly any")),
    conmedic = factor(conmedic, levels = 1:3, labels = c("a great deal", "only some", "hardly any"))
  )

# Full time series (for timeline examples)
gss_timeline <- gss_all %>%
  select(year, happy) %>%
  filter(happy %in% 1:3, !is.na(year)) %>%
  mutate(happy = droplevels(as_factor(happy)))

πŸ“¦ What Content Collections Store

A content collection is a container that holds visualizations, content blocks, interactive inputs, and layout helpers. Here’s what you can add:

Category Types Functions
Visualizations Bar, Stacked Bar, Histogram, Density, Boxplot, Timeline, Heatmap, Scatter, Treemap, Map add_viz(), add_vizzes()
Content Blocks Text, Callouts, Cards, Accordions, Quotes, Badges, Metrics, Value Boxes, Code, Images, Videos, iframes, HTML add_text(), add_callout(), add_card(), add_accordion(), add_quote(), add_badge(), add_metric(), add_value_box(), add_code(), add_image(), add_html()
Tables & Custom Charts gt Tables, Reactable, DT DataTables, Basic Tables, Custom Highcharter Charts add_gt(), add_reactable(), add_DT(), add_table(), add_hc()
Interactive Inputs (see Advanced Features) Dropdowns, Checkboxes, Sliders, Radio buttons add_input_row(), add_input()
Layout Helpers Dividers, Spacers, Pagination markers add_divider(), add_spacer(), add_pagination()

Everything is stored in a unified items list, and you can inspect it anytime:

content <- create_content(data = gss, type = "bar") %>%
  add_viz(x_var = "degree", title = "Education") %>%
  add_text("## Analysis", "", "Key findings:") %>%
  add_callout(paste0("Sample size: ", nrow(gss)), type = "note")

print(content)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 3 items | βœ” data: 2997 rows x 15 cols
#> 
#> β€’ [Viz] Education (bar) x=degree
#> β„Ή [Text]
#> ⚠ [Callout]
preview(content)
Preview
Education
Analysis

Key findings:

NOTE

Sample size: 2997

βš™οΈ The Defaults System

The defaults system lets you set once, use many times. Instead of repeating the same parameters for every visualization, you define them once in create_content() and they automatically apply to all add_viz() calls.

Why Use Defaults?

Without defaults, you’d need to repeat parameters for every chart:

# Repetitive - don't do this!
content %>%
  add_viz(x_var = "age", type = "bar", color_palette = c("#3498DB"), bar_type = "percent") %>%
  add_viz(x_var = "sex", type = "bar", color_palette = c("#3498DB"), bar_type = "percent") %>%
  add_viz(x_var = "race", type = "bar", color_palette = c("#3498DB"), bar_type = "percent")

With defaults, you set them once and they flow through:

# Clean - do this!
create_content(data = gss, type = "bar", color_palette = c("#3498DB"), bar_type = "percent") %>%
  add_viz(x_var = "age") %>%
  add_viz(x_var = "sex") %>%
  add_viz(x_var = "race")

Override Hierarchy

Parameters are resolved in this order (later wins):

  1. Collection defaults - set in create_content()
  2. Individual viz settings - set in add_viz()

This means you can set sensible defaults for most charts, then override specific ones as needed:

# Default: horizontal percent bars in blue
content <- create_content(
  data = gss,
  type = "bar",
  bar_type = "percent",
  horizontal = TRUE,
  color_palette = c("#3498DB")
) %>%
  # Uses all defaults
  add_viz(x_var = "degree", title = "Education") %>%
  # Override: vertical instead of horizontal
  add_viz(x_var = "race", title = "Race (vertical)", horizontal = FALSE) %>%
  # Override: count instead of percent
  add_viz(x_var = "sex", title = "Sex (count)", bar_type = "count")

print(content)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 3 items | βœ” data: 2997 rows x 15 cols
#> 
#> β€’ [Viz] Education (bar) x=degree
#> β€’ [Viz] Race (vertical) (bar) x=race
#> β€’ [Viz] Sex (count) (bar) x=sex
content %>% preview()
Preview
Education
Race (vertical)
Sex (count)

Any Parameter Can Be a Default

Any parameter you can pass to add_viz() can be set as a default in create_content(). Common ones include:

Parameter Description Example Values
type Visualization type "bar", "histogram", "stackedbar", "timeline"
color_palette Colors for charts c("#3498DB", "#E74C3C")
bar_type Bar chart display "count", "percent", "mean"
horizontal Flip chart orientation TRUE, FALSE
weight_var Survey weight column "wtssps"
drop_na_vars Remove NA values TRUE, FALSE
stacked_type Stacked bar display "count", "percent"
bins Histogram bins 20, 30, 50
x_label Custom x-axis label "Age (years)"
y_label Custom y-axis label "Number of Respondents"
tooltip_suffix Text after tooltip values "%", " people"
error_bars Error bar type (for bar_type = "mean") "none", "sd", "se", "ci"
value_var Numeric variable for means "score", "income"

See the Visualization Types section for all parameters available for each chart type.

🏷️ Custom Labels and Tooltips

Every visualization supports custom axis labels and tooltip formatting. These help make your charts clearer and more professional.

Axis Labels

By default, dashboardr uses your variable names as axis labels. Override them with x_label and y_label:

# Without custom labels (uses variable names)
create_content(data = gss, type = "bar") %>%
  add_viz(x_var = "degree", title = "Education Levels") %>%
  preview()
Preview
Education Levels
# With custom labels (more polished)
create_content(data = gss, type = "bar") %>%
  add_viz(
    x_var = "degree", 
    title = "Education Levels",
    x_label = "Highest Degree Earned",
    y_label = "Number of Respondents"
  ) %>%
  preview()
Preview
Education Levels

For stacked charts, you can also set stack_label to customize the legend title:

create_content(data = gss, type = "stackedbar") %>%
  add_viz(
    x_var = "degree", 
    stack_var = "sex",
    title = "Education by Gender",
    x_label = "Highest Degree",
    y_label = "Count",
    stack_label = "Gender"
  ) %>%
  preview()
Preview
Education by Gender

Tooltip Customization

Tooltips are the interactive popups that appear when users hover over data points. Customize them with prefix and suffix options:

Parameter Description Example
tooltip_prefix Text before the value "Count: ", "$"
tooltip_suffix Text after the value "%", " respondents"
x_tooltip_suffix Text after x-axis value " years", " USD"
# Add units to tooltips
create_content(data = gss, type = "histogram") %>%
  add_viz(
    x_var = "age", 
    title = "Age Distribution",
    x_label = "Age",
    y_label = "Count",
    tooltip_suffix = " respondents",
    x_tooltip_suffix = " years old"
  ) %>%
  preview()
Preview
Age Distribution
# Percentage tooltips for stacked bars
create_content(data = gss, type = "stackedbar") %>%
  add_viz(
    x_var = "happy", 
    stack_var = "sex",
    title = "Happiness by Gender",
    stacked_type = "percent",
    y_label = "Percentage",
    tooltip_suffix = "%"
  ) %>%
  preview()
Preview
Happiness by Gender

Tip: Labels and tooltip settings can also be set as collection defaults in create_content(), so they apply to all visualizations:

# Set tooltip suffix as a default for all charts
create_content(
  data = gss, 
  type = "bar",
  bar_type = "percent",
  tooltip_suffix = "%",
  y_label = "Percentage"
) %>%
  add_viz(x_var = "degree", title = "Education") %>%
  add_viz(x_var = "race", title = "Race") %>%
  preview()
Preview
Education
Race

βž• Combining Collections

The + Operator

Merge collections while preserving structure:

demographics <- create_content(data = gss, type = "bar") %>%
  add_viz(x_var = "degree", title = "Education", tabgroup = "Demo")

attitudes <- create_content(data = gss, type = "bar") %>%
  add_viz(x_var = "happy", title = "Happiness", tabgroup = "Attitudes")

combined <- demographics + attitudes
print(combined)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 2 items | βœ” data: 2997 rows x 15 cols
#> 
#> ❯ [Tab] Demo (1 viz)
#>   β€’ [Viz] Education (bar) x=degree
#> ❯ [Tab] Attitudes (1 viz)
#>   β€’ [Viz] Happiness (bar) x=happy
combined %>% preview()
Preview
Education
Happiness

combine_viz()

Same as + but in pipe-friendly form:

all_content <- demographics %>%
  combine_viz(attitudes)

print(all_content)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 2 items | βœ” data: 2997 rows x 15 cols
#> 
#> ❯ [Tab] Demo (1 viz)
#>   β€’ [Viz] Education (bar) x=degree
#> ❯ [Tab] Attitudes (1 viz)
#>   β€’ [Viz] Happiness (bar) x=happy

πŸ“Š Visualization Types

dashboardr supports 11 visualization types. Each is optimized for different data patterns. For detailed documentation on each type, see the individual vignettes: - Bar Charts | Stacked Bars - Histograms | Density Plots | Box Plots - Timelines | Heatmaps | Scatter Plots - Treemaps | Maps

Bar Charts

Bar charts are the workhorse of categorical data. Use them when you want to compare counts or proportions across categories.

The simplest bar chart counts occurrences of each category:

create_content(data = gss, type = "bar") %>%
  add_viz(x_var = "degree", title = "Education Levels") %>%
  preview()
Preview
Education Levels

Often you’ll want percentages instead of raw counts. Set bar_type = "percent" to show proportions that sum to 100%:

create_content(data = gss, type = "bar") %>%
  add_viz(x_var = "race", title = "Race Distribution", bar_type = "percent") %>%
  preview()
Preview
Race Distribution

To compare categories across groups, add group_var. This creates side-by-side bars:

create_content(data = gss, type = "bar") %>%
  add_viz(x_var = "degree", group_var = "sex", title = "Education by Sex") %>%
  preview()
Preview
Education by Sex

For long category labels, flip to horizontal with horizontal = TRUE:

create_content(data = gss, type = "bar") %>%
  add_viz(x_var = "degree", title = "Education (Horizontal)", horizontal = TRUE) %>%
  preview()
Preview
Education (Horizontal)

Means with Error Bars

For numeric outcomes, use bar_type = "mean" with error_bars to show statistical uncertainty:

# Sample data with numeric scores
score_data <- data.frame(
  group = rep(c("Control", "Treatment"), each = 50),
  score = c(rnorm(50, 70, 10), rnorm(50, 78, 12))
)

create_content(data = score_data, type = "bar") %>%
  add_viz(
    x_var = "group",
    value_var = "score",
    bar_type = "mean",
    error_bars = "ci",           # "sd", "se", or "ci"
    title = "Mean Scores (95% CI)"
  ) %>%
  preview()
Preview
Mean Scores (95% CI)
Error Type Parameter Shows
Standard Deviation error_bars = "sd" Spread of individual values
Standard Error error_bars = "se" Precision of mean estimate
Confidence Interval error_bars = "ci" Range likely to contain true mean

See the Bar Chart vignette for more options including grouped means and error bar styling.

Stacked Bars

Stacked bars show composition - how a whole breaks down into parts. Use stack_var to specify what fills each bar.

This shows the happiness distribution within each education level as raw counts:

create_content(data = gss, type = "stackedbar") %>%
  add_viz(x_var = "degree", stack_var = "happy", title = "Happiness by Education") %>%
  preview()
Preview
Happiness by Education

For easier comparison across groups of different sizes, use stacked_type = "percent". Now each bar sums to 100%, making patterns clearer:

create_content(data = gss, type = "stackedbar") %>%
  add_viz(x_var = "degree", stack_var = "happy", title = "Happiness by Education (%)",
          stacked_type = "percent") %>%
  preview()
Preview
Happiness by Education (%)

Horizontal stacked bars work well when you have many categories or long labels:

create_content(data = gss, type = "stackedbar") %>%
  add_viz(x_var = "degree", stack_var = "happy", title = "Horizontal Stacked",
          stacked_type = "percent", horizontal = TRUE) %>%
  preview()
Preview
Horizontal Stacked

See the Stacked Bar vignette for more options.

Histograms

Histograms show the distribution of continuous variables. The bins parameter controls granularity - more bins show more detail, fewer bins show smoother patterns.

create_content(data = gss, type = "histogram") %>%
  add_viz(x_var = "age", title = "Age Distribution", bins = 25,
          x_label = "Age (years)", y_label = "Frequency") %>%
  preview()
Preview
Age Distribution

See the Histogram vignette for more options.

Density Plots

Density plots show smooth estimates of the distribution of a continuous variable. They’re useful when you want a cleaner view of the distribution shape compared to histograms.

create_content(data = gss, type = "density") %>%
  add_viz(x_var = "age", title = "Age Distribution (Density)",
          x_label = "Age (years)") %>%
  preview()
Preview
Age Distribution (Density)

Add group_var to compare distributions across groups:

create_content(data = gss, type = "density") %>%
  add_viz(x_var = "age", group_var = "sex", 
          title = "Age Distribution by Sex") %>%
  preview()
Preview
Age Distribution by Sex

See the Density vignette for more options.

Box Plots

Box plots (also called box-and-whisker plots) show the distribution of a numeric variable across categories. They display the median, quartiles, and outliers, making it easy to compare distributions.

create_content(data = gss, type = "boxplot") %>%
  add_viz(x_var = "degree", y_var = "age", 
          title = "Age Distribution by Education Level",
          x_label = "Highest Degree", y_label = "Age") %>%
  preview()
Preview
Age Distribution by Education Level

See the Box Plot vignette for more options.

Multiple Stacked Bars (Likert Scales)

When you have multiple survey questions with the same response scale (like Likert items), use type = "stackedbar" with x_vars to display them together for comparison. This is perfect for β€œconfidence in institutions” batteries or agreement scales.

Use x_vars for the question columns and x_var_labels for readable labels. Note: These confidence questions use a split-ballot design, so ~1/3 of respondents have NA (question not asked). We use drop_na_vars = TRUE to exclude those:

create_content(data = gss, type = "stackedbar", drop_na_vars = TRUE) %>%
  add_viz(
    x_vars = c("confinan", "conbus", "coneduc", "confed", "conmedic"),
    x_var_labels = c("Banks & financial institutions", 
                     "Major companies",
                     "Education",
                     "Federal government",
                     "Medicine"),
    title = "Confidence in Institutions",
    stacked_type = "percent",
    horizontal = TRUE
  ) %>%
  preview()
Preview
Confidence in Institutions

See the Stacked Bar vignette for more options including multi-question mode.

Timeline

Timeline charts track how responses change over time. You need a time variable (time_var) and a response variable (y_var). Unlike other chart types, timelines need data spanning multiple time periods.

create_content(data = gss_timeline, type = "timeline") %>%
  add_viz(
    time_var = "year",
    y_var = "happy",
    title = "Happiness Over Time",
    chart_type = "line"
  ) %>%
  preview()
Preview
Happiness Over Time

Use chart_type = "stacked_area" for a stacked area chart, which emphasizes cumulative patterns:

create_content(data = gss_timeline, type = "timeline") %>%
  add_viz(
    time_var = "year",
    y_var = "happy",
    title = "Happiness Trends (Stacked Area)",
    chart_type = "stacked_area"
  ) %>%
  preview()
Preview
Happiness Trends (Stacked Area)

See the Timeline vignette for more options.

Heatmap

Heatmaps visualize how a numeric value varies across two categorical dimensions, displayed as a color-coded grid. Each cell shows the aggregated value for that combination of categories.

Required parameters:

Parameter Description
x_var Categorical variable for columns
y_var Categorical variable for rows
value_var Numeric variable to aggregate and color by

How it works: The heatmap automatically aggregates value_var for each unique combination of x_var and y_var. By default, it calculates the mean - so if you have 50 people with a bachelor’s degree who are β€œvery happy”, the cell shows their average age.

create_content(data = gss, type = "heatmap") %>%
  add_viz(
    x_var = "degree",
    y_var = "happy",
    value_var = "age",
    title = "Average Age by Education & Happiness"
  ) %>%
  preview()
Preview
Average Age by Education & Happiness

Key optional parameters:

Parameter Description Default
agg_fun Aggregation function mean
color_palette Two colors for gradient (low, high) c("#FFFFFF", "#7CB5EC")
color_min / color_max Fixed color scale bounds Auto from data
x_order / y_order Custom category ordering Auto
data_labels_enabled Show values in cells TRUE
weight_var Column for weighted aggregation NULL

Change the aggregation function with agg_fun. Use any R function that takes a vector and returns a single value:

# Median instead of mean
create_content(data = gss, type = "heatmap") %>%
  add_viz(
    x_var = "degree",
    y_var = "happy",
    value_var = "age",
    agg_fun = median,
    title = "Median Age by Education & Happiness"
  ) %>%
  preview()
Preview
Median Age by Education & Happiness

Customize the color gradient with color_palette - provide low and high colors:

create_content(data = gss, type = "heatmap") %>%
  add_viz(
    x_var = "degree",
    y_var = "happy",
    value_var = "age",
    title = "Custom Colors (Red gradient)",
    color_palette = c("#FFF5F0", "#67000D")
  ) %>%
  preview()
Preview
Custom Colors (Red gradient)

Use survey weights for proper weighted means:

create_content(data = gss, type = "heatmap") %>%
  add_viz(
    x_var = "degree",
    y_var = "happy",
    value_var = "age",
    weight_var = "wtssps",
    title = "Weighted Average Age"
  ) %>%
  preview()
Preview
Weighted Average Age

See the Heatmap vignette for more options.

Scatter Plots

Scatter plots show relationships between two numeric variables. Each point represents one observation. Key parameters:

  • x_var - Variable for horizontal axis
  • y_var - Variable for vertical axis
  • color_var - Optional grouping variable for colored points
  • size_var - Optional variable to control point sizes
  • show_trend - Add a trend line (TRUE/FALSE)
  • alpha - Point transparency (0-1)
# Filter to respondents with valid education and children data
scatter_data <- gss %>%
  filter(!is.na(educ), !is.na(childs))

create_content(data = scatter_data, type = "scatter") %>%
  add_viz(
    x_var = "educ",
    y_var = "childs",
    color_var = "sex",
    title = "Education vs Number of Children",
    x_label = "Years of Education",
    y_label = "Number of Children",
    alpha = 0.4
  ) %>%
  preview()
Preview
Education vs Number of Children

See the Scatter Plot vignette for more options.

Treemap

Treemaps display hierarchical data as nested rectangles. The size of each rectangle represents its value - larger rectangles mean larger values. Great for showing composition and proportions across many categories.

Important: Treemaps require pre-aggregated data with a value column. You typically need to count() or summarize() your data first.

Key parameters:

  • group_var - Primary grouping variable (creates the rectangles)
  • subgroup_var - Optional secondary grouping for hierarchical treemaps
  • value_var - Numeric column that determines rectangle size
  • color_var - Optional variable for coloring (defaults to group_var)
# Treemaps need pre-aggregated data
degree_counts <- gss %>%
  count(degree, name = "n")

create_content(data = degree_counts, type = "treemap") %>%
  add_viz(
    group_var = "degree",
    value_var = "n",
    title = "Education Distribution"
  ) %>%
  preview()
Preview
Education Distribution

For hierarchical treemaps, add subgroup_var:

# Two-level hierarchy: degree within sex
degree_sex_counts <- gss %>%
  count(sex, degree, name = "n")

create_content(data = degree_sex_counts, type = "treemap") %>%
  add_viz(
    group_var = "sex",
    subgroup_var = "degree",
    value_var = "n",
    title = "Education by Sex"
  ) %>%
  preview()
Preview
Education by Sex

See the Treemap vignette for more options.

Map

Geographic maps (choropleths) display data across regions using color intensity. Each region is shaded based on a numeric value, making it easy to see geographic patterns at a glance.

Key parameters:

Parameter Description
value_var Numeric column for color intensity
join_var Column with geographic codes (must match map’s internal codes)
map_type Map geography: "custom/world", "countries/us/us-all", etc.
color_palette Two colors for gradient (low, high)
tooltip_vars Variables to show in hover tooltips

Important: Maps require geographic identifier codes that match the map’s internal region codes:

  • World maps: Use 2-letter ISO country codes (iso2c): β€œUS”, β€œDE”, β€œFR”, etc.
  • US state maps: Use postal codes: β€œCA”, β€œNY”, β€œTX”, etc.
# Load gapminder data and add ISO country codes
library(gapminder)
library(countrycode)

# Get latest year and convert country names to ISO codes
map_data <- gapminder %>%
  filter(year == max(year)) %>%
  mutate(iso2c = countrycode(country, "country.name", "iso2c")) %>%
  filter(!is.na(iso2c))

Now create a world map showing life expectancy:

create_content(data = map_data, type = "map") %>%
  add_viz(
    value_var = "lifeExp",
    join_var = "iso2c",
    map_type = "custom/world",
    title = "Life Expectancy by Country (2007)",
    color_palette = c("#fee5d9", "#a50f15")
  ) %>%
  preview()
Preview
Life Expectancy by Country (2007)

Custom color palettes - use any two colors for the gradient:

create_content(data = map_data, type = "map") %>%
  add_viz(
    value_var = "gdpPercap",
    join_var = "iso2c",
    map_type = "custom/world",
    title = "GDP per Capita",
    color_palette = c("#f7fbff", "#08306b")  # Light to dark blue
  ) %>%
  preview()
Preview
GDP per Capita

Available map types:

Map Type Region Join Key
"custom/world" World countries iso2c (2-letter ISO)
"custom/world-highres" World (high resolution) iso2c
"countries/us/us-all" US states Postal codes (β€œCA”, β€œNY”)
"countries/de/de-all" German states State codes
"custom/europe" European countries iso2c

See the Map vignette for more options.

πŸ“ Organizing with Tabgroups

Tabgroups create tabbed interfaces in your dashboard:

content <- create_content(data = gss, type = "bar") %>%
  add_viz(x_var = "degree", title = "Education", tabgroup = "demographics") %>%
  add_viz(x_var = "race", title = "Race", tabgroup = "demographics") %>%
  add_viz(x_var = "happy", title = "Happiness", tabgroup = "attitudes") %>%
  add_viz(x_var = "polviews", title = "Politics", tabgroup = "attitudes")

print(content)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 4 items | βœ” data: 2997 rows x 15 cols
#> 
#> ❯ [Tab] demographics (2 vizs)
#>   β€’ [Viz] Education (bar) x=degree
#>   β€’ [Viz] Race (bar) x=race
#> ❯ [Tab] attitudes (2 vizs)
#>   β€’ [Viz] Happiness (bar) x=happy
#>   β€’ [Viz] Politics (bar) x=polviews

Nested Tabgroups

For complex dashboards, you can create multi-level tab hierarchies using / as a separator:

nested <- create_content(data = gss, type = "bar") %>%
  # Top-level: "Demographics" with two sub-tabs
  add_viz(x_var = "degree", title = "Education Level", 
          tabgroup = "Demographics/Education") %>%
  add_viz(x_var = "race", title = "Race Distribution", 
          tabgroup = "Demographics/Race") %>%
  add_viz(x_var = "age", title = "Age Distribution", 
          tabgroup = "Demographics/Age") %>%
  # Top-level: "Attitudes" with sub-tabs
  add_viz(x_var = "happy", title = "General Happiness", 
          tabgroup = "Attitudes/Wellbeing") %>%
  add_viz(x_var = "polviews", title = "Political Views", 
          tabgroup = "Attitudes/Politics")

print(nested)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 5 items | βœ” data: 2997 rows x 15 cols
#> 
#> ❯ [Tab] Demographics (3 tabs)
#>   ❯ [Tab] Education (1 viz)
#>     β€’ [Viz] Education Level (bar) x=degree
#>   ❯ [Tab] Race (1 viz)
#>     β€’ [Viz] Race Distribution (bar) x=race
#>   ❯ [Tab] Age (1 viz)
#>     β€’ [Viz] Age Distribution (bar) x=age
#> ❯ [Tab] Attitudes (2 tabs)
#>   ❯ [Tab] Wellbeing (1 viz)
#>     β€’ [Viz] General Happiness (bar) x=happy
#>   ❯ [Tab] Politics (1 viz)
#>     β€’ [Viz] Political Views (bar) x=polviews
preview(nested)
Preview
Education Level
Race Distribution
Age Distribution
General Happiness
Political Views

Custom Tab Labels

Replace tabgroup IDs with readable labels using set_tabgroup_labels():

labeled <- create_content(data = gss, type = "bar") %>%
  add_viz(x_var = "degree", title = "Education", tabgroup = "demo") %>%
  add_viz(x_var = "happy", title = "Happiness", tabgroup = "attitudes") %>%
  set_tabgroup_labels(
    demo = "Demographics",
    attitudes = "Attitudes & Values"
  )

print(labeled)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 2 items | βœ” data: 2997 rows x 15 cols
#> 
#> ❯ [Tab] demo (1 viz)
#>   β€’ [Viz] Education (bar) x=degree
#> ❯ [Tab] attitudes (1 viz)
#>   β€’ [Viz] Happiness (bar) x=happy
labeled %>% preview()
Preview
Education
Happiness

πŸ“ Content Blocks

Content blocks add non-visualization elements to your collections.

Text Blocks

add_text() is a flexible function for adding markdown content. It has several smart features:

Multiple arguments become lines - Pass as many strings as you want, and they join with newlines:

create_content() %>%
  add_text(
    "## Survey Overview",
    "",
    "The General Social Survey (GSS) has been conducted since 1972.",
    "It covers demographics, attitudes, and social behaviors."
  ) %>%
  preview()
Preview
Survey Overview

The General Social Survey (GSS) has been conducted since 1972. It covers demographics, attitudes, and social behaviors.

Use empty strings for spacing - An empty "" creates a paragraph break:

create_content() %>%
  add_text(
    "## Section One",
    "",
    "First paragraph of content.",
    "",
    "## Section Two",
    "",
    "Second paragraph with a gap above."
  ) %>%
  preview()
Preview
Section One

First paragraph of content.

Section Two

Second paragraph with a gap above.

Full Markdown support - Headers, lists, bold, italic, links, and more:

text_example <- create_content() %>%
  add_text(
    "## Key Findings",
    "",
    "This analysis reveals **three important patterns**:",
    "",
    "1. Education correlates with happiness",
    "2. Age distribution is *roughly normal*",
    "3. Political views show [polarization](https://en.wikipedia.org/wiki/Political_polarization)",
    "",
    "### Methodology Note",
    "",
    "> Data weighted using GSS survey weights"
  )

print(text_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 1 items | βœ– no data
#> 
#> β„Ή [Text]
text_example %>% preview()
Preview
Key Findings

This analysis reveals three important patterns:

  1. Education correlates with happiness
  2. Age distribution is roughly normal
  3. Political views show polarization
Methodology Note

Data weighted using GSS survey weights

Works standalone or in pipes - Call it directly or chain it:

# Standalone - returns a content block
block <- add_text("# Title")

# In a pipe - adds to existing collection
content %>% add_text("More content here")

Callouts

Callouts draw attention to specific information with colored boxes and icons. Use them to highlight notes, tips, warnings, or critical information that readers shouldn’t miss.

Five types for different purposes:

Type Use for Color
note Additional context, background info Blue
tip Helpful suggestions, best practices Green
warning Potential issues, things to watch out for Yellow
caution Proceed carefully, possible problems Orange
important Critical information, must-read Red
callout_gallery <- create_content() %>%
  add_callout("Notes provide additional context or information.", type = "note", title = "Note") %>%
  add_callout("Tips offer helpful suggestions to improve workflow.", type = "tip", title = "Pro Tip") %>%
  add_callout("Warnings alert users to potential issues.", type = "warning", title = "Warning") %>%
  add_callout("Caution indicates something that needs careful attention.", type = "caution", title = "Caution") %>%
  add_callout("Important highlights critical information.", type = "important", title = "Important")

print(callout_gallery)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 5 items | βœ– no data
#> 
#> ⚠ [Callout] Note
#> ⚠ [Callout] Pro Tip
#> ⚠ [Callout] Warning
#> ⚠ [Callout] Caution
#> ⚠ [Callout] Important
callout_gallery %>% preview()
Preview
Note

Notes provide additional context or information.

Pro Tip

Tips offer helpful suggestions to improve workflow.

Warning

Warnings alert users to potential issues.

Caution

Caution indicates something that needs careful attention.

Important

Important highlights critical information.

Custom titles are optional - If you omit title, the type name is used:

create_content() %>%
  add_callout("Sample size is smaller than recommended for this analysis.", type = "warning") %>%
  preview()
Preview
WARNING

Sample size is smaller than recommended for this analysis.

Practical example - Combine callouts with visualizations:

create_content(data = gss, type = "bar") %>%
  add_callout("This chart shows unweighted counts. See methodology for weighted estimates.", type = "note") %>%
  add_viz(x_var = "degree", title = "Education Distribution") %>%
  add_callout("Education data may reflect selection bias in survey response rates.", type = "tip", title = "Interpretation Tip") %>%
  preview()
Preview
NOTE

This chart shows unweighted counts. See methodology for weighted estimates.

Education Distribution
Interpretation Tip

Education data may reflect selection bias in survey response rates.

Cards

Styled content containers with optional titles:

card_example <- create_content() %>%
  add_card(
    title = "Key Finding",
    text = "Education level shows a strong positive correlation with reported happiness levels across all demographic groups."
  ) %>%
  add_card(
    text = "Cards without titles work too. Great for quick content blocks."
  )

print(card_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 2 items | βœ– no data
#> 
#> β—Ό [Card] Key Finding
#> β—Ό [Card]
card_example %>% preview()
Preview
Key Finding

Education level shows a strong positive correlation with reported happiness levels across all demographic groups.

Cards without titles work too. Great for quick content blocks.

Accordions

Collapsible sections for supplementary or detailed content:

accordion_example <- create_content() %>%
  add_accordion(
    title = "Click to expand: Methodology",
    text = "This analysis uses weighted survey data from NORC. Sample size: 21,788 respondents."
  ) %>%
  add_accordion(
    title = "Click to expand: Data Sources",
    text = "General Social Survey (GSS), collected annually since 1972."
  )

print(accordion_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 2 items | βœ– no data
#> 
#> ☰ [Accordion] Click to expand: Methodology
#> ☰ [Accordion] Click to expand: Data Sources
accordion_example %>% preview()
Preview
Click to expand: Methodology

This analysis uses weighted survey data from NORC. Sample size: 21,788 respondents.

Click to expand: Data Sources

General Social Survey (GSS), collected annually since 1972.

Quotes

Block quotes with optional attribution:

quote_example <- create_content() %>%
  add_quote(
    quote = "The only true wisdom is in knowing you know nothing.",
    attribution = "Socrates"
  )

print(quote_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 1 items | βœ– no data
#> 
#> β€’ [quote]
quote_example %>% preview()
Preview

The only true wisdom is in knowing you know nothing.

β€” Socrates

Badges

Inline status indicators:

badge_example <- create_content() %>%
  add_text("Status indicators:") %>%
  add_badge("Complete", color = "success") %>%
  add_badge("In Progress", color = "warning") %>%
  add_badge("Not Started", color = "danger") %>%
  add_badge("Info", color = "info") %>%
  add_badge("Primary", color = "primary") %>%
  add_badge("Secondary", color = "secondary")

print(badge_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 7 items | βœ– no data
#> 
#> β„Ή [Text]
#> β€’ [badge]
#> β€’ [badge]
#> β€’ [badge]
#> β€’ [badge]
#> β€’ [badge]
#> β€’ [badge]
badge_example %>% preview()
Preview

Status indicators:

Complete In Progress Not Started Info Primary Secondary

Metrics

Single KPI value boxes:

metric_example <- create_content() %>%
  add_metric(
    title = "Total Respondents",
    value = "21,788",
    icon = "ph:users"
  )

print(metric_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 1 items | βœ– no data
#> 
#> β€’ [metric] Total Respondents
metric_example %>% preview()
Preview
ph:users
21,788
Total Respondents

Value Boxes

Custom-styled value boxes with branding:

value_box_example <- create_content() %>%
  add_value_box(
    title = "Revenue",
    value = "$1.2M",
    bg_color = "#27AE60"
  )

print(value_box_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 1 items | βœ– no data
#> 
#> β€’ [value_box] Revenue
value_box_example %>% preview()
Preview
Revenue
$1.2M

Value Box Rows

Multiple value boxes in a responsive row:

value_row_example <- create_content() %>%
  add_value_box_row() %>%
    add_value_box(title = "Users", value = "12,345", bg_color = "#3498DB") %>%
    add_value_box(title = "Sessions", value = "45,678", bg_color = "#9B59B6") %>%
    add_value_box(title = "Conversion", value = "3.2%", bg_color = "#E74C3C") %>%
  end_value_box_row()

print(value_row_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 1 items | βœ– no data
#> 
#> β€’ [value_box_row]
value_row_example %>% preview()
Preview
Users
12,345
Sessions
45,678
Conversion
3.2%

Code Blocks

Syntax-highlighted code snippets:

code_example <- create_content() %>%
  add_code(
    code = "library(dashboardr)\n\ncreate_content(data = df) %>%\n  add_viz(type = 'bar', x_var = 'category')",
    language = "r"
  )

print(code_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 1 items | βœ– no data
#> 
#> β€’ [Code]
code_example %>% preview()
Preview
library(dashboardr)

create_content(data = df) %>%
  add_viz(type = 'bar', x_var = 'category')

Images

Add images with optional captions. Use full URLs for images to ensure they display on GitHub Pages:

image_example <- create_content() %>%
  add_image(
    src = "https://favstats.github.io/dashboardr/reference/figures/logo.svg",
    alt = "dashboardr Logo",
    caption = "The dashboardr package logo",
    width = "200px"
  )

print(image_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 1 items | βœ– no data
#> 
#> β—‰ [Image]
image_example %>% preview()
Preview
The dashboardr package logo
The dashboardr package logo

Tip: Always use absolute URLs (starting with https://) for images in vignettes. Local file paths like "logo.png" work during development but won’t display on GitHub Pages or pkgdown sites.

Videos

For local video files, use add_video() - but note these won’t work on GitHub Pages unless hosted elsewhere:

# Local video (works locally, not on GitHub)
create_content() %>%
  add_video(
    src = "presentation.mp4",
    caption = "Project overview video"
  )

For video content, use YouTube or Vimeo embeds via add_iframe() - this is more reliable than direct video files:

# YouTube embed (recommended approach)
video_example <- create_content() %>%
  add_iframe(
    src = "https://www.youtube.com/embed/dQw4w9WgXcQ",
    height = "315px"
  )

print(video_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 1 items | βœ– no data
#> 
#> β€’ [iframe]
video_example %>% preview()
Preview

iframes

Embed external content like interactive maps, dashboards, or other web pages:

iframe_example <- create_content() %>%
  add_iframe(
    src = "https://www.openstreetmap.org/export/embed.html?bbox=-0.1%2C51.5%2C0.0%2C51.52",
    height = "300px"
  )

print(iframe_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 1 items | βœ– no data
#> 
#> β€’ [iframe]
iframe_example %>% preview()
Preview

Raw HTML

Insert custom HTML when needed:

html_example <- create_content() %>%
  add_html('<div style="background: linear-gradient(to right, #667eea, #764ba2); color: white; padding: 20px; border-radius: 8px; text-align: center;"><h3>Custom HTML Block</h3><p>Style anything with raw HTML!</p></div>')

print(html_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 1 items | βœ– no data
#> 
#> β€’ [html]
html_example %>% preview()
Preview

Custom HTML Block

Style anything with raw HTML!

πŸ“Š Tables and Custom Charts

Beyond visualizations created with add_viz(), you can embed tables and custom charts directly into content collections.

gt Tables

Use add_gt() to embed publication-quality tables created with the gt package:

# Create a summary table
summary_data <- gss %>%
  group_by(degree) %>%
  summarise(
    n = n(),
    mean_age = round(mean(age, na.rm = TRUE), 1),
    .groups = "drop"
  )

gt_example <- create_content() %>%
  add_text("### Summary Statistics by Education") %>%
  add_gt(
    gt::gt(summary_data) %>%
      gt::cols_label(degree = "Education", n = "Count", mean_age = "Mean Age")
  )

print(gt_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 2 items | βœ– no data
#> 
#> β„Ή [Text]
#> β€’ [gt]
gt_example %>% preview()
Preview
Summary Statistics by Education
Education Count Mean Age
less than high school 242 49.5
high school 1361 50.0
associate/junior college 277 49.6
bachelor's 677 51.0
graduate 440 52.5

You can also pass a data frame directly - it will be converted to a gt table automatically:

simple_gt <- create_content() %>%
  add_gt(head(summary_data, 3), caption = "Top 3 Education Levels")

simple_gt %>% preview()
Preview
degree n mean_age
less than high school 242 49.5
high school 1361 50.0
associate/junior college 277 49.6

Reactable Tables

For interactive tables with sorting and filtering, use add_reactable():

reactable_example <- create_content() %>%
  add_text("### Interactive Summary Table") %>%
  add_reactable(
    reactable::reactable(summary_data, searchable = TRUE, striped = TRUE)
  )

print(reactable_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 2 items | βœ– no data
#> 
#> β„Ή [Text]
#> β€’ [reactable]
reactable_example %>% preview()
Preview
Interactive Summary Table

DT DataTables

For feature-rich interactive tables, use add_DT():

dt_example <- create_content() %>%
  add_text("### DataTable with Search and Pagination") %>%
  add_DT(summary_data, options = list(pageLength = 5))

print(dt_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 2 items | βœ– no data
#> 
#> β„Ή [Text]
#> β€’ [DT]
dt_example %>% preview()
Preview
DataTable with Search and Pagination

Basic Tables

For simple tables without dependencies, use add_table():

table_example <- create_content() %>%
  add_table(head(summary_data, 3), caption = "Sample Data")

print(table_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 1 items | βœ– no data
#> 
#> β€’ [table]
table_example %>% preview()
Preview
Sample Data
degree n mean_age
less than high school 242 49.5
high school 1361 50
associate/junior college 277 49.6

Custom Highcharter Charts

When you need a visualization that goes beyond what add_viz() offers, use add_hc() to embed any highcharter chart:

library(highcharter)

# Create a custom chart
custom_chart <- highchart() %>%
  hc_chart(type = "pie") %>%
  hc_title(text = "Education Distribution") %>%
  hc_add_series(
    name = "Count",
    data = list(
      list(name = "Less than HS", y = sum(gss$degree == "less than high school")),
      list(name = "High School", y = sum(gss$degree == "high school")),
      list(name = "Junior College", y = sum(gss$degree == "junior college")),
      list(name = "Bachelor", y = sum(gss$degree == "bachelor")),
      list(name = "Graduate", y = sum(gss$degree == "graduate"))
    )
  )

hc_example <- create_content() %>%
  add_text("### Custom Pie Chart") %>%
  add_hc(custom_chart)

print(hc_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 2 items | βœ– no data
#> 
#> β„Ή [Text]
#> β€’ [hc]
hc_example %>% preview()
Preview
Custom Pie Chart

This is useful for:

  • Chart types not available in add_viz() (pie charts, gauges, etc.)
  • Highly customized visualizations
  • Integrating existing highcharter code

πŸ“ˆ Working with Pre-aggregated Data

While dashboardr was designed with survey data in mind (where you typically count or aggregate responses), it works equally well with data that’s already aggregated.

Bar Charts with Pre-aggregated Data

Use the y_var parameter to specify a column containing pre-computed values:

# Pre-aggregated data (e.g., from a database or API)
country_stats <- data.frame(
  country = c("USA", "Germany", "France", "UK", "Japan"),
  population_millions = c(331, 83, 67, 67, 126),
  gdp_trillions = c(21.4, 3.8, 2.6, 2.8, 5.1)
)

# Use y_var to plot pre-aggregated values directly
preagg_bar <- create_content(data = country_stats) %>%
  add_viz(
    type = "bar",
    x_var = "country",
    y_var = "population_millions",  # Pre-computed values
    title = "Population by Country (Millions)",
    x_order = c("USA", "Japan", "Germany", "UK", "France")
  )

preagg_bar %>% preview()
Preview
Population by Country (Millions)

This also works for grouped bar charts:

# Pre-aggregated grouped data
quarterly_sales <- data.frame(
  quarter = rep(c("Q1", "Q2", "Q3", "Q4"), each = 2),
  region = rep(c("North", "South"), 4),
  revenue = c(100, 80, 120, 95, 150, 110, 130, 100)
)

grouped_preagg <- create_content(data = quarterly_sales) %>%
  add_viz(
    type = "bar",
    x_var = "quarter",
    group_var = "region",
    y_var = "revenue",
    title = "Quarterly Revenue by Region"
  )

grouped_preagg %>% preview()
Preview
Quarterly Revenue by Region

Stacked Bars with Pre-aggregated Data

The y_var parameter works the same way for stacked bar charts:

# Pre-aggregated stacked data
satisfaction_data <- data.frame(
  department = rep(c("Sales", "Engineering", "HR"), each = 3),
  rating = rep(c("Satisfied", "Neutral", "Dissatisfied"), 3),
  count = c(45, 30, 10, 60, 25, 15, 35, 20, 5)
)

stacked_preagg <- create_content(data = satisfaction_data) %>%
  add_viz(
    type = "stackedbar",
    x_var = "department",
    stack_var = "rating",
    y_var = "count",  # Pre-computed counts
    title = "Employee Satisfaction by Department"
  )

stacked_preagg %>% preview()
Preview
Employee Satisfaction by Department

Histograms with Pre-aggregated Data

For pre-binned histogram data:

# Pre-binned data (e.g., from a reporting system)
age_bins <- data.frame(
  age_group = c("18-25", "26-35", "36-45", "46-55", "56-65", "65+"),
  count = c(150, 280, 320, 290, 210, 180)
)

hist_preagg <- create_content(data = age_bins) %>%
  add_viz(
    type = "histogram",
    x_var = "age_group",
    y_var = "count",  # Pre-computed bin counts
    title = "Age Distribution"
  )

hist_preagg %>% preview()
Preview
Age Distribution

Timelines with Pre-aggregated Data

Use agg = "none" to skip aggregation for timeline data:

# Pre-aggregated time series
yearly_metrics <- data.frame(
  year = c(2020, 2021, 2022, 2023),
  value = c(1250, 1380, 1420, 1510)
)

timeline_preagg <- create_content(data = yearly_metrics) %>%
  add_viz(
    type = "timeline",
    time_var = "year",
    y_var = "value",
    agg = "none",  # Use values directly, no aggregation
    title = "Yearly Performance Trend"
  )

timeline_preagg %>% preview()
Preview
Yearly Performance Trend

Heatmaps with Pre-aggregated Data

Use pre_aggregated = TRUE to skip the aggregation step:

# Pre-computed heatmap values (one row per cell)
correlation_data <- data.frame(
  var1 = rep(c("Age", "Income", "Education"), each = 3),
  var2 = rep(c("Age", "Income", "Education"), 3),
  correlation = c(1.0, 0.35, 0.28, 0.35, 1.0, 0.52, 0.28, 0.52, 1.0)
)

heatmap_preagg <- create_content(data = correlation_data) %>%
  add_viz(
    type = "heatmap",
    x_var = "var1",
    y_var = "var2",
    value_var = "correlation",
    pre_aggregated = TRUE,  # Skip aggregation
    title = "Correlation Matrix",
    color_min = -1,
    color_max = 1
  )

heatmap_preagg %>% preview()
Preview
Correlation Matrix

Treemaps with Pre-aggregated Data

Use pre_aggregated = TRUE to use values directly without summing:

# Pre-aggregated hierarchical data
budget_data <- data.frame(
  category = c("Marketing", "Marketing", "Engineering", "Engineering", "Operations"),
  subcategory = c("Digital", "Events", "Frontend", "Backend", "Support"),
  amount = c(50000, 30000, 80000, 120000, 45000)
)

treemap_preagg <- create_content(data = budget_data) %>%
  add_viz(
    type = "treemap",
    group_var = "category",
    subgroup_var = "subcategory",
    value_var = "amount",
    pre_aggregated = TRUE,  # Use amounts directly
    title = "Budget Allocation"
  )

treemap_preagg %>% preview()
Preview
Budget Allocation

πŸ”² Layout Helpers

Dividers

Visual separators between content sections:

divider_content <- create_content(data = gss, type = "bar") %>%
  add_viz(x_var = "degree", title = "Education") %>%
  add_divider() %>%
  add_viz(x_var = "happy", title = "Happiness")

print(divider_content)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 3 items | βœ” data: 2997 rows x 15 cols
#> 
#> β€’ [Viz] Education (bar) x=degree
#> ─ [Divider]
#> β€’ [Viz] Happiness (bar) x=happy
divider_content %>% preview()
Preview
Education

Happiness

Spacers

Add vertical spacing between elements:

spacer_example <- create_content() %>%
  add_text("Content above") %>%
  add_spacer(height = "3rem") %>%
  add_text("Content below (after 3rem spacer)")

print(spacer_example)
#> -- Content Collection ──────────────────────────────────────────────────────────
#> 3 items | βœ– no data
#> 
#> β„Ή [Text]
#> β€’ [spacer]
#> β„Ή [Text]
spacer_example %>% preview()
Preview

Content above

Content below (after 3rem spacer)

πŸ‘οΈ Previewing Content

Use preview() to quickly check your visualizations and content blocks during development. It automatically validates your visualization specs and catches errors like missing parameters or invalid column names before rendering:

# Quick preview (fast, no Quarto)
content %>% preview()

# Full Quarto preview (slower, full features)
content %>% preview(quarto = TRUE)

# Save to specific location
content %>% preview(path = "my_preview.html")

Limitations of Preview

Important: preview() is a simplified rendering for quick checks during development. It does not show the final dashboard appearance.

What preview shows well:

  • Individual visualizations and their data
  • Basic tabgroup organization
  • Content blocks (text, callouts, cards, etc.)
  • Simple nested tabs

What preview does NOT support:

  • Full dashboard navigation and layout
  • Interactive inputs (dropdowns, sliders, checkboxes)
  • Complex multi-page structures
  • Dashboard theming and styling
  • Sidebar navigation
  • Mobile responsiveness

For a real view of your dashboard, you must run generate_dashboard() and open the resulting Quarto site:

dashboard <- create_dashboard("My Dashboard") %>%

  add_page(my_page)

# Generate the full dashboard
generate_dashboard(dashboard)

# Then open _site/index.html in your browser

Think of preview() as a β€œsanity check” for your charts and content, not a representation of the final product.

➑️ Next Steps

Once you have content, add it to a page:

create_page("Analysis", data = gss) %>%
  add_content(demographics) %>%
  add_content(attitudes)

See vignette("pages") for page creation details.