Iframe Embedding
embedding.RmdvizRd can run as a full Shiny app or as a compact embedded
visualization. Use embed=1 in the query string to hide
nonessential app chrome while preserving the controls required by the
requested view.
Build embed URLs
vizRd::build_embed_url(
base_url = "https://example.org/vizrd/",
dataset = "excises",
view = "scatter",
x_metric = "specific_excise_eur_1_000",
y_metric = "ad_valorem_rate",
year = 2025,
embed = TRUE
)Useful query parameters include dataset,
view, metric, x_metric,
y_metric, year, date,
geos, area_mode, area_series, and
embed=1. For template area views, area_mode is
allowlisted to absolute or percent.
area_series is read only for view=area; it
stores displayed series labels after Top-N plus Other aggregation and
can include the generated Other label.
For generic explorer states, use
vizRd::build_share_url() with chart,
numeric, numeric2, category,
datetime, and group as needed.
Area share and embed states
Area share/embed recipes use geos for the
pre-aggregation candidate filter and area_series for
post-contract isolation. The default all-visible area state omits
area_series; non-default selections keep the isolated
labels in the URL.
vizRd::build_share_url(
base_url = "https://example.org/vizrd/",
dataset = "excises",
view = "area",
metric = "total_excise_duty_eur_1_000",
geos = c("AUT", "DEU", "FRA"),
area_mode = "percent",
area_series = c("AUT", "Other")
)
vizRd::build_embed_url(
base_url = "https://example.org/vizrd/",
dataset = "excises",
view = "area",
metric = "total_excise_duty_eur_1_000",
area_mode = "absolute",
area_series = "Other",
embed = TRUE
)The same query can be used directly as an iframe
src:
https://example.org/vizrd/?dataset=excises&view=area&metric=total_excise_duty_eur_1_000&area_mode=percent&area_series=AUT%2COther&embed=1
If stale area_series values are shared, vizRd retains
valid displayed labels, drops unknown labels, and falls back to all
displayed series when none remain. Percent-mode guardrails still apply
inside embeds; invalid percent states show absolute values with the same
fallback copy as the full app.
Copy snippets from vizRd
The Actions panel includes a read-only Share URL field
and an Embed code textarea for the current state. The
generated iframe snippet uses build_iframe_snippet(),
forces embed=1, and includes a host-side
vizrd:resize listener.
You can build the same snippet from R:
vizRd::build_iframe_snippet(
src = vizRd::build_share_url(
base_url = "https://example.org/vizrd/",
dataset = "generic_sales",
chart = "overview"
)
)Gallery route
Open ?gallery=1 on a running vizRd app to browse
datasets and copy ready-made share URLs and iframe snippets.
https://example.org/vizrd/?gallery=1
The packaged example project also includes a small host-page fixture
at /vizrd-project/embed-host.html when the app is running.
Use it for manual UAT by pasting a copied share URL or iframe
src; it forces embed=1 and reports received
vizrd:resize messages.
Resize bridge
The embedded app serves a package-local child-side bridge from
vizrd/vendor/open-iframe-resizer-core.js. The bridge emits
vizrd:resize messages to the parent window. The host page
owns origin checks and iframe height updates.
Same-origin iframe
Use embed=1 in the iframe URL so vizRd trims
nonessential chrome.
<iframe
id="vizrd-frame"
src="/vizrd/?dataset=excises&view=area&metric=total_excise_duty_eur_1_000&geos=AUT%2CDEU&area_mode=percent&area_series=AUT%2COther&embed=1"
width="100%"
style="border:0; min-height:520px;"
loading="lazy"
></iframe>
<script>
window.addEventListener("message", function(event) {
var frame = document.getElementById("vizrd-frame");
if (!frame || event.source !== frame.contentWindow) {
return;
}
var data = event.data || {};
if (data.type === "vizrd:resize" && Number.isFinite(data.height)) {
frame.style.height = Math.min(10000, Math.max(320, data.height)) + "px";
}
});
</script>Cross-origin iframe
For cross-origin embeds, keep the source-window check and add a strict origin check for the deployed vizRd app host.
<iframe
id="vizrd-frame"
src="https://viz.example.org/?dataset=excises&view=area&metric=total_excise_duty_eur_1_000&geos=AUT%2CDEU&area_mode=absolute&area_series=Other&embed=1"
width="100%"
style="border:0; min-height:520px;"
loading="lazy"
></iframe>
<script>
var vizrdOrigin = "https://viz.example.org";
window.addEventListener("message", function(event) {
var frame = document.getElementById("vizrd-frame");
if (!frame || event.origin !== vizrdOrigin || event.source !== frame.contentWindow) {
return;
}
var data = event.data || {};
if (data.type === "vizrd:resize" && Number.isFinite(data.height)) {
frame.style.height = Math.min(10000, Math.max(320, data.height)) + "px";
}
});
</script>Open Iframe Resizer can be used on host pages in future if vizRd
replaces the local bridge with a protocol-compatible child asset. With
the current packaged bridge, use the vizrd:resize listener
shown above.
Fixed-height fallback
Hosts that cannot run JavaScript can use a fixed iframe height. Automatic resizing is disabled, but the embedded visualization remains usable.
Troubleshooting
- If the gallery does not open, confirm the URL includes
gallery=1. - Confirm the iframe
srcincludesembed=1. - Confirm the deployed app serves
vizrd/vendor/open-iframe-resizer-core.js. - Confirm the host page includes a
messagelistener forvizrd:resize. - For cross-origin embeds, confirm the
event.origincheck exactly matches the vizRd app origin. - Check whether host-page CSS is forcing a fixed iframe height and overriding dynamic resizing.
- If the iframe stays blank, verify the
dataset,view,metric,geos,area_mode,area_series,year, anddatequery parameters againstbuild_embed_url().