shinyseo

CRAN version CRAN total downloads

shinyseo is a small helper package for Shiny apps that need social, search, and PWA metadata.

It builds one shiny::tags$head() fragment containing:

The package accepts either a YAML file path or a named list.

Six exported functions:

Getting started

Run shinyseo::init_meta() in the console. It will ask for your title, description, URL, image, and a handful of optional fields (favicon, theme colour, home screen shortcut support, and so on), then write the answers to meta.yml. Pass that file straight to social_meta():

shinyseo::social_meta("meta.yml")

What it does

When you call social_meta(), the package:

  1. Reads metadata from YAML or uses the list you pass in.
  2. Fills in safe defaults for common fields like locale, robots, and Twitter card type.
  3. Checks that the required fields exist.
  4. Builds HTML tags for Shiny UI.
  5. Adds JSON-LD unless you turn schema off.
  6. Registers a JavaScript handler so update_meta() can update tags at runtime.

API in short

social_meta(meta):

update_meta(session, title, description, url, image):

write_manifest(meta, path, display, start_url, background_color):

generate_assets(meta, generator, path, assets):

meta <- shinyseo::generate_assets(meta,
  generator = shinyseo::openai_image_generator()
)
yaml::write_yaml(meta, "meta.yml")

Or supply your own, against whatever service you already have access to:

meta <- shinyseo::generate_assets(meta, generator = function(prompt, kind) {
  # your own call to Adobe Firefly, a local model, ...
})
yaml::write_yaml(meta, "meta.yml")

openai_image_generator(api_key, model):

meta <- shinyseo::generate_assets(meta,
  generator = shinyseo::openai_image_generator(api_key = "sk-...")
)

Config cheat sheet

Minimal configuration:

title: "Example app"
description: "A short app description."
url: "https://example.no"
image: "https://example.no/share.png"

Common extras:

Field What it does
locale Sets Open Graph locale and schema language default
robots Controls the robots meta tag
twitter_card Sets the Twitter card type
site_name Sets og:site_name
twitter_site Sets twitter:site
twitter_creator Sets twitter:creator
image_alt Sets og:image:alt
twitter_image_alt Sets twitter:image:alt
favicon Sets <link rel="icon"> with auto-detected MIME type
favicon_type Overrides the MIME type inferred from favicon
favicon_png Adds a PNG <link rel="icon"> fallback — set this when favicon is an SVG; Chromium address bars don’t render SVG favicons and show a generic globe icon without a PNG fallback
favicon_png_sizes Overrides the sizes attribute on favicon_png (defaults to "32x32")
apple_touch_icon Sets <link rel="apple-touch-icon">
theme_color Sets <meta name="theme-color">
manifest Sets <link rel="manifest">
short_name Used by write_manifest() for the manifest short name
apple_mobile_web_app_capable Set to TRUE to run standalone when added to a phone’s home screen (apple-mobile-web-app-capable and mobile-web-app-capable)
apple_mobile_web_app_title Sets the name shown under the home screen icon (apple-mobile-web-app-title)
apple_mobile_web_app_status_bar_style Sets the iOS status bar style (apple-mobile-web-app-status-bar-style)
custom List of lists — each becomes an arbitrary <meta> tag
bing_site_verification Sets Bing verification
google_site_verification Sets Google Search Console verification
yandex_site_verification Sets Yandex Webmaster verification
baidu_site_verification Sets Baidu Webmaster verification
naver_site_verification Sets Naver Webmaster verification
facebook_domain_verification Sets Facebook domain verification
pinterest_domain_verification Sets Pinterest domain verification
schema Set to FALSE to disable JSON-LD

If you want shared defaults across several apps, you can set these in .Renviron and let app-level YAML override them when needed:

What belongs where

Use .Renviron for values that are shared across many apps on the same machine or deployment:

Keep per-app values in each app’s meta.yml:

SHINYSEO_GOOGLE_ANALYTICS_MEASUREMENT_ID is not used by shinyseo itself. If you use GA4, keep that in your server or deployment config instead of in meta.yml.

Quick use

# global.R — generate manifest once at startup
shinyseo::write_manifest("meta.yml")

# ui.R
ui <- fluidPage(
  shinyseo::social_meta("meta.yml"),
  h1("My app")
)

# server.R — update metadata when the user navigates
server <- function(input, output, session) {
  observeEvent(input$tabs, {
    shinyseo::update_meta(session, title = paste(input$tabs, "– My App"))
  })
}

You can also pass a list directly instead of a YAML file:

shinyseo::social_meta(list(
  title       = "Example app",
  description = "A short app description.",
  url         = "https://example.no",
  image       = "https://example.no/share.png",
  favicon     = "/favicon.png",
  theme_color = "#1a73e8"
))

Vignettes

The long-form package docs live in vignettes:

If the package is installed, you can also open them with browseVignettes("shinyseo").

For LLM use, see LLM.md.

mirror server hosted at Truenetwork, Russian Federation.