Docs
Preview
Overview
Basic Preview
The preview content block renders a live URL preview in an iframe with device switcher controls. By default, it displays in desktop view.
https://en.wikipedia.org/wiki/Hugo_(software).
Open in new tab
https://en.wikipedia.org/wiki/Hugo_(software).
Open in new tab
https://en.wikipedia.org/wiki/Hugo_(software).
Open in new tab
- _bookshop_name: preview
heading:
title: Hugo on Wikipedia
content: Live preview of the Hugo static site generator Wikipedia page
url: "https://en.wikipedia.org/wiki/Hugo_(software)"Preview With Specific Device
Set the device argument to specify which device view to display by default. Options are desktop, tablet, or mobile.
https://en.wikipedia.org/wiki/Hugo_(software).
Open in new tab
https://en.wikipedia.org/wiki/Hugo_(software).
Open in new tab
https://en.wikipedia.org/wiki/Hugo_(software).
Open in new tab
- _bookshop_name: preview
heading:
title: Tablet Preview
content: Opens in tablet view (820×1180 logical pixels)
url: "https://en.wikipedia.org/wiki/Hugo_(software)"
device: tabletControls Below Preview
By default the device switcher appears above the preview. Set controls_placement: bottom to move it below the preview area instead.
https://en.wikipedia.org/wiki/Hugo_(software).
Open in new tab
https://en.wikipedia.org/wiki/Hugo_(software).
Open in new tab
https://en.wikipedia.org/wiki/Hugo_(software).
Open in new tab
- _bookshop_name: preview
heading:
title: Controls Below
content: Device switcher placed beneath the preview
url: "https://en.wikipedia.org/wiki/Hugo_(software)"
controls_placement: bottomStrict Aspect Ratio
By default the desktop preview fills the full container width and height (responsive mode). Set desktop_responsive: false to use a strict 16:10 contain fit instead — the full 1440 × 900px frame is always visible with no clipping, leaving symmetric gaps above and below when the container is wider than it is tall.
https://en.wikipedia.org/wiki/Hugo_(software).
Open in new tab
https://en.wikipedia.org/wiki/Hugo_(software).
Open in new tab
https://en.wikipedia.org/wiki/Hugo_(software).
Open in new tab
- _bookshop_name: preview
heading:
title: Strict Aspect Ratio
content: Full 1440×900px frame always visible, no clipping
url: "https://en.wikipedia.org/wiki/Hugo_(software)"
device: desktop
desktop_responsive: falseFull-Width Preview
Use cover: true and fluid: true for a full-width preview layout, ideal for showcasing responsive designs.
https://en.wikipedia.org/wiki/Hugo_(software).
Open in new tab
https://en.wikipedia.org/wiki/Hugo_(software).
Open in new tab
https://en.wikipedia.org/wiki/Hugo_(software).
Open in new tab
- _bookshop_name: preview
heading:
title: Full-Width Preview
content: Responsive design showcase
background:
color: body-tertiary
subtle: true
width: 12
cover: true
fluid: true
url: "https://en.wikipedia.org/wiki/Hugo_(software)"
device: desktopEmbedded Map Example
The preview component works well with embeddable content like OpenStreetMap . This example demonstrates a full-width preview with custom background styling.
https://www.openstreetmap.org/export/embed.html?bbox=-0.1,51.5,-0.08,51.52.
Open in new tab
https://www.openstreetmap.org/export/embed.html?bbox=-0.1,51.5,-0.08,51.52.
Open in new tab
https://www.openstreetmap.org/export/embed.html?bbox=-0.1,51.5,-0.08,51.52.
Open in new tab
- _bookshop_name: preview
heading:
title: "Embedded Map"
content: "OpenStreetMap embed URL - specifically designed for iframes"
background:
color: body-tertiary
subtle: true
width: 12
cover: true
fluid: false
url: "https://www.openstreetmap.org/export/embed.html?bbox=-0.1,51.5,-0.08,51.52"
device: desktopBlocked URL With Fallback Image
When the target URL sets X-Frame-Options or Content-Security-Policy: frame-ancestors 'none', Hugo detects this at build time via a HEAD request and renders the error overlay server-side. Provide an image argument to display a representative screenshot in place of the blocked iframe. The warning alert with a direct link is still shown below the image.
Set show-fallback: true to force the error overlay explicitly — useful when the HEAD request cannot reach the target URL (offline or CI environments), or when the URL blocks embedding for your specific domain without using the headers detected above.
https://google.com.
Open in new tab
https://google.com.
Open in new tab
https://google.com.
Open in new tab
- _bookshop_name: preview
heading:
title: Preview unavailable
content: This URL blocks iframe embedding — a fallback image is shown instead
url: "https://google.com"
image: /img/placeholder.pngBlocked URL Without Fallback Image
Without an image argument the component shows only the warning alert when the iframe fails to load, with a link to open the URL directly in a new tab.
https://google.com.
Open in new tab
https://google.com.
Open in new tab
https://google.com.
Open in new tab
- _bookshop_name: preview
heading:
title: Preview unavailable (alert only)
content: No fallback image — only the warning alert is displayed
url: "https://google.com"CSP Configuration
The preview component embeds external URLs in iframes, which requires appropriate Content Security Policy (CSP) configuration.
Production Configuration
For production environments, explicitly allow the domains you want to embed in your config/production/params.toml:
[modules.hinode.csp]
frame-src = [
"https:", # Allow all HTTPS sources
"example.com", # Specific domain
"*.yourdomain.com", # Wildcard subdomain
"*.googletagmanager.com",
"player.cloudinary.com",
"www.youtube-nocookie.com",
"www.youtube.com",
"player.vimeo.com"
]Development Configuration
For local development, allow HTTP sources in your config/development/params.toml:
[modules.hinode.csp]
frame-src = [
"http:", # Allow all HTTP for localhost
"https:",
"*.googletagmanager.com",
"player.cloudinary.com",
"www.youtube-nocookie.com",
"www.youtube.com",
"player.vimeo.com"
]This allows embedding localhost sites during development while maintaining security in production.
Hugo Security Configuration
Build-time embedding detection issues a HEAD request to each preview URL during the build. Hugo’s default security policy only allows GET and POST methods. Add the following to your site’s config/_default/hugo.toml to enable HEAD requests:
[security]
[security.http]
methods = ['(?i)GET|POST|HEAD']
urls = ['.*']Without this setting, the HEAD requests are silently blocked and embedding restrictions are not detected. Use show-fallback: true to force the fallback explicitly — it is not affected by this setting.
Embedding Restrictions
Many websites prevent iframe embedding using X-Frame-Options or Content-Security-Policy response headers. Hugo issues a HEAD request to each preview URL at build time and inspects the response headers. Detection coverage:
| Response header | Build-time action |
|---|---|
X-Frame-Options (any value) |
Fallback rendered — blocks all cross-origin embedding |
Content-Security-Policy: frame-ancestors 'none' |
Fallback rendered — blocks all embedding |
Content-Security-Policy: frame-ancestors with specific domains |
No action — domain-specific; whether the iframe loads depends on the deployment domain |
| No relevant headers | No action — embedding allowed by default |
For frame-ancestors with specific domains (e.g. 'self' example.com *.example.com), Hugo cannot determine at build time whether the iframe will load on your site, since the allowed origins depend on the deployment domain. If you know a URL will not embed on your site, use show-fallback: true to render the fallback explicitly.
Best practices:
- Use the preview component for sites you control or that explicitly allow embedding
- Test URLs in development before deploying
- Set
imageto a representative screenshot so users see meaningful content when embedding is blocked - Use
show-fallback: truein offline or CI environments where the HEAD request cannot reach the target URL, or when a URL restricts embedding via domain-specificframe-ancestorsheaders - Use embeddable alternatives (e.g., youtube-nocookie.com instead of youtube.com)
Device Dimensions
Device dimensions use logical pixels (CSS pixels), which is what browsers and responsive design tools use for layout. Physical pixels depend on the device pixel ratio (DPR) of the hardware display.
| Device | Logical resolution | Aspect ratio | DPR reference |
|---|---|---|---|
| Desktop | 1440 × 900px | 16:10 | @1× (MacBook / laptop) |
| Tablet | 820 × 1180px | ~9:13 | @2× (iPad 10th gen / iPad Air M2) |
| Mobile | 402 × 874px | 9:19.5 | @3× (iPhone 17 Pro, 460 ppi) |
A website loaded inside the iframe sees a viewport matching these logical pixel dimensions, so breakpoints and responsive layouts behave exactly as they would on the real device.
Auto-Scaling
JavaScript scales each device on page load and on every browser resize. Tablet and mobile always use a contain fit — the largest scale where neither dimension is clipped:
scale = min(containerWidth / deviceWidth, containerHeight / deviceHeight, 1)Desktop scaling depends on the desktop_responsive argument:
| Mode | desktop_responsive |
Behaviour |
|---|---|---|
| Responsive (default) | true |
Scales to fill the full container width; iframe height is adjusted dynamically so the container height is also filled. The site inside sees a 1440px-wide viewport. |
| Strict aspect ratio | false |
Contain fit — the full 1440 × 900px frame is always visible; symmetric gaps may appear above and below on wide containers. |
The zoom recalculates on page load and whenever the browser window is resized.
Container height adapts to available viewport space and is capped so tall devices (tablet: 1180px logical) are never rendered beyond the available screen area:
height: min(calc(100vh - controls - navbar - 4rem),
calc(var(--max-section-height, 1024px) - controls));
min-height: 400px;Responsive Visibility
The component automatically shows or hides device previews based on viewport width only:
- Small screens (< 640px): Mobile preview only
- Medium screens (640px–1023px): Tablet and mobile previews
- Large screens (≥ 1024px): All three previews
Buttons for hidden device views are automatically hidden from the control bar, and the active view automatically switches when a panel becomes unavailable.
Container Constraints
In responsive mode (default), the desktop preview fills whatever container it is placed in. For best results with desktop_responsive: false or when using cover: true:
- Use
fluid: trueorwidth: 12for full-width layouts - Use a container at least as wide as the desired desktop zoom level
Security
The preview component includes iframe sandboxing for security:
sandbox="allow-scripts allow-same-origin allow-forms allow-popups"This restricts iframe capabilities while allowing:
- JavaScript execution (
allow-scripts) - Access to same-origin resources (
allow-same-origin) - Form submissions (
allow-forms) - Opening popups/new windows (
allow-popups)
Arguments
The content block supports the following arguments:
| Name | Type | Required | Default | Comment |
|---|---|---|---|---|
| _bookshop_name | string | Alias for _bookshop_name. | ||
| _ordinal | int | Zero-based position of the bookshop component within the page’s component hierarchy. | ||
| background | background, string | Background style of the section. | ||
| bg_class | string | Background class attributes of the element. It supports Bootstrap attributes to modify the background styling of the element. | ||
| controls_placement | select | top |
Position of the device selection button group relative to the preview area. Use “top” (default) to place the controls above the preview, or “bottom” to place them below. Supported values: [top, bottom]. |
|
| cover | bool | Flag indicating if the element should be rendered fullscreen. | ||
| desktop_responsive | bool | true |
Controls how the desktop iframe scales within the preview container. When true (default), the iframe fills the full container width and height by adjusting its logical height dynamically — the website inside sees a 1440px-wide viewport at the current zoom level. When false, the desktop uses a strict 16:10 contain fit so the full 1440 × 900px frame is always visible with no clipping. | |
| device | select | desktop |
Device view to display by default in preview component. Determines the initial iframe dimensions and active tab. Supported values: [desktop, tablet, mobile]. |
|
| fluid | bool | true |
Flag to set the section container to fluid design, else the section is limited to xxl. |
|
| heading | Heading | Heading of the content block, including a preheading and content element. | ||
| id | string | Unique identifier of the current element. | ||
| image | string | Image to include in the content block or section heading. | ||
| justify | select | start |
Justification of the child elements. Supported values: [start, end, center, between, around, evenly]. |
|
| mode | bool | Flag indicating if the media asset should support color modes. If set, the element searches for images having a matching color-mode suffix such as -light or -dark. |
||
| overlay_mode | select | Overlay mode of the element, overrides the site’s general configuration. Supported values: [light, dark, none]. |
||
| section_class | string | Section class attributes of the element. It supports Bootstrap attributes to modify the section styling of the element. | ||
| show_fallback | bool | Forces the error overlay to be rendered server-side, bypassing build-time detection. Useful in offline or CI environments where the HEAD request cannot reach the target URL. | ||
| theme | select | Color theme to apply to the element. Supported values: [light, dark]. |
||
| url | string, template.URL | yes | Address of the link destination, either a local reference or an external address. Include the scheme when referencing an external address, such as https://google.com. Local references may include an optional anchor link such as blog/bootstrap-elements/#docs. |
|
| width | int | 8 |
Column width of the element. For embedded elements, the width is relative to the parent’s container. | |
| wrapper | string | Class attribute of the element’s wrapper. It supports Bootstrap attributes to modify the styling of the element. Icons include the fa-wrapper and fa-fluid attributes by default. |
| Name | Type | Required | Default |
|---|---|---|---|
| _bookshop_name | string | ||
| Alias for _bookshop_name. | |||
| _ordinal | int | ||
| Zero-based position of the bookshop component within the page’s component hierarchy. | |||
| background | background, string | ||
| Background style of the section. | |||
| bg_class | string | ||
| Background class attributes of the element. It supports Bootstrap attributes to modify the background styling of the element. | |||
| controls_placement | select | top |
|
Position of the device selection button group relative to the preview area. Use “top” (default) to place the controls above the preview, or “bottom” to place them below. Supported values: [top, bottom]. |
|||
| cover | bool | ||
| Flag indicating if the element should be rendered fullscreen. | |||
| desktop_responsive | bool | true |
|
| Controls how the desktop iframe scales within the preview container. When true (default), the iframe fills the full container width and height by adjusting its logical height dynamically — the website inside sees a 1440px-wide viewport at the current zoom level. When false, the desktop uses a strict 16:10 contain fit so the full 1440 × 900px frame is always visible with no clipping. | |||
| device | select | desktop |
|
Device view to display by default in preview component. Determines the initial iframe dimensions and active tab. Supported values: [desktop, tablet, mobile]. |
|||
| fluid | bool | true |
|
Flag to set the section container to fluid design, else the section is limited to xxl. |
|||
| heading | Heading | ||
| Heading of the content block, including a preheading and content element. | |||
| id | string | ||
| Unique identifier of the current element. | |||
| image | string | ||
| Image to include in the content block or section heading. | |||
| justify | select | start |
|
Justification of the child elements. Supported values: [start, end, center, between, around, evenly]. |
|||
| mode | bool | ||
Flag indicating if the media asset should support color modes. If set, the element searches for images having a matching color-mode suffix such as -light or -dark. |
|||
| overlay_mode | select | ||
Overlay mode of the element, overrides the site’s general configuration. Supported values: [light, dark, none]. |
|||
| section_class | string | ||
| Section class attributes of the element. It supports Bootstrap attributes to modify the section styling of the element. | |||
| show_fallback | bool | ||
| Forces the error overlay to be rendered server-side, bypassing build-time detection. Useful in offline or CI environments where the HEAD request cannot reach the target URL. | |||
| theme | select | ||
Color theme to apply to the element. Supported values: [light, dark]. |
|||
| url | string, template.URL | yes | |
Address of the link destination, either a local reference or an external address. Include the scheme when referencing an external address, such as https://google.com. Local references may include an optional anchor link such as blog/bootstrap-elements/#docs. |
|||
| width | int | 8 |
|
| Column width of the element. For embedded elements, the width is relative to the parent’s container. | |||
| wrapper | string | ||
Class attribute of the element’s wrapper. It supports Bootstrap attributes to modify the styling of the element. Icons include the fa-wrapper and fa-fluid attributes by default. |
|||
Background Type
| Name | Type | Required | Default | Comment |
|---|---|---|---|---|
| backdrop | string | Background image with a mask to improve contrast. | ||
| class | string | Class attributes of the element. It supports Bootstrap attributes to modify the styling of the element. | ||
| color | select | Theme color of the element. Supported values: [primary, secondary, success, danger, warning, info, light, dark, white, black, body, body-tertiary]. |
||
| subtle | bool | Apply subtle theme colors. |
| Name | Type | Required | Default |
|---|---|---|---|
| backdrop | string | ||
| Background image with a mask to improve contrast. | |||
| class | string | ||
| Class attributes of the element. It supports Bootstrap attributes to modify the styling of the element. | |||
| color | select | ||
Theme color of the element. Supported values: [primary, secondary, success, danger, warning, info, light, dark, white, black, body, body-tertiary]. |
|||
| subtle | bool | ||
| Apply subtle theme colors. | |||
Heading Type
| Name | Type | Required | Default | Comment |
|---|---|---|---|---|
| align | select | start |
Alignment of the headline, content, or icon. Supported values: [start, center, end]. |
|
| arrangement | select | above |
Arrangement of the preheading, either left or above the header. On smaller screens, the preheading is always placed on top. Supported values: [above, first]. |
|
| content | string, template.HTML | Section content displayed below the title. | ||
| preheading | string | Preheading of the section heading. | ||
| size | int | 4 |
Display size of the headline. | |
| title | string, hstring.RenderedString, hstring.HTML, template.HTML | Title of the element. If the element references a (local) page, the title overrides the referenced page’s title. | ||
| width | int | 8 |
Column width of the element. For embedded elements, the width is relative to the parent’s container. |
| Name | Type | Required | Default |
|---|---|---|---|
| align | select | start |
|
Alignment of the headline, content, or icon. Supported values: [start, center, end]. |
|||
| arrangement | select | above |
|
Arrangement of the preheading, either left or above the header. On smaller screens, the preheading is always placed on top. Supported values: [above, first]. |
|||
| content | string, template.HTML | ||
| Section content displayed below the title. | |||
| preheading | string | ||
| Preheading of the section heading. | |||
| size | int | 4 |
|
| Display size of the headline. | |||
| title | string, hstring.RenderedString, hstring.HTML, template.HTML | ||
| Title of the element. If the element references a (local) page, the title overrides the referenced page’s title. | |||
| width | int | 8 |
|
| Column width of the element. For embedded elements, the width is relative to the parent’s container. | |||