"Look" what you'll see on your website: this extension shows content elements
in the TYPO3 page module exactly as they appear in the frontend, rendered with
the real templates, CSS and images of your site, inside an isolated preview
frame.
The TYPO3 page module normally shows a content element as a plain summary: a
headline, the first lines of text, maybe a thumbnail. Editors have to open the
frontend to see what they actually built.
Look changes that. It renders every content element with the real frontend
templates, stylesheets and images of your website and shows the result
directly in the page module, scaled down to fit. What you see in the backend
is what visitors get on the website.
Content elements in the page module, rendered with the frontend design of
the site.
Each preview lives in its own isolated frame. It looks like the frontend
but cannot interact with the backend: no clicks, no scripts of the page
content, no access to the editor's session. The frame adapts its height to
the content automatically, so short and tall elements both look natural.
A text and media element as editors see it: the frontend layout with
headline, copy and image.
Who is it for?
Editors see the effect of every setting immediately: a different
header layout, a coloured section, an image position. No more switching
between backend and frontend. With the edit overlay enabled, a click on
the preview opens the element for editing.
Integrators reuse the frontend templates they already have. A preview
is one Fluid tag around the existing rendering, there is no second
template to keep in sync.
Administrators get previews that are safe by default. Scripts and
media of the website are switched off inside the preview until they are
explicitly allowed, see Security.
How does it work?
Look ships one Fluid view helper, <look:backend.contentPreview>. You
wrap it around the frontend markup of a content element, typically in the
backend preview template of a Content Block. The view helper
renders the markup you pass it,
puts it into a complete HTML document together with the stylesheets and
scripts of your site,
and shows that document in a sandboxed <iframe> in the page module.
The frame reports its content height to the backend, so the page module
always shows the whole element (or a fixed height with a fade-out, if you
prefer). Everything else, from the design to the icons, comes from your own
frontend build.
Compatibility
Look version
TYPO3 version
PHP version
main
13.4 LTS, 14.3+
8.2 or later
Installation
Install with Composer
Look is installed like any other TYPO3 extension in a Composer based project:
composer require flowd/typo3-look
Copied!
Afterwards set up the extension so that TYPO3 picks up its configuration:
vendor/bin/typo3 extension:setup
Copied!
That is all for the extension itself. The previews appear as soon as a
content element uses the view helper, see Usage.
If your frontend uses web fonts
Look needs no web server configuration. One case is the exception: the preview
frame runs with an opaque origin, and browsers fetch web fonts and JavaScript
modules from such a frame as cross-origin requests. They only load if the
server answers with Access-Control-Allow-Origin: * for the path they
come from.
This affects web fonts of your frontend build, and the scripts of your build
when you enable allowSiteScripts. Without
the header the previews still work, they just use fallback fonts. Images,
stylesheets and videos are not affected.
The header is safe for public static files, it grants read access to bytes
that are served publicly anyway and browsers never combine * with
credentials. Do not add it to dynamic or authenticated paths.
Check the installation
Open a page in the page module that contains a content element with a Look
preview. You should see the element in the frontend design, scaled down. If
you see the plain TYPO3 preview instead, the content element type does not use
the view helper yet. If the frame stays empty or shows a red callout, see
Known problems and how to solve.
Usage
Look provides a single Fluid view helper. Wrap it around the frontend markup
of a content element and the page module shows that markup as a real preview.
Content Blocks
render the file templates/backend-preview.html of a content block in
the page module. Reuse the frontend rendering there and wrap it in the view
helper:
<f:layout name="Preview" /> with a Content section is the
layout Content Blocks provides for backend previews. Without it, Content
Blocks renders the template three times (header, content, footer) and the
preview appears three times.
The markup inside the view helper is whatever your frontend template
produces. Here it is a Fluid component that receives the record; it could
just as well be a partial or plain HTML. Wrapping the element in the same
container markup as the frontend (<main class="page-content">)
makes sure the grid and spacing rules of your CSS apply.
css and js take the assets of your frontend build. They
are loaded inside the preview frame only, never in the backend itself.
Section backgrounds, decorative borders and buttons come from the site's
own stylesheet.
Previews for classic content elements
Content element types without Content Blocks can use the view helper in the
Fluid template that TYPO3 renders for the page module preview. Register the
template with page TSconfig:
Factor the frontend is scaled down with inside the preview. 0.5
shows the site at half size, 1 at its natural size. The frame
is always as wide as the page module column; the scale decides how
much of the frontend width fits into it.
Maximum height of the preview in pixels. Elements that are taller are
cut off and fade out at the bottom, so editors see that there is more.
0 means no limit: the frame grows with its content.
A preview with height="250". The fade-out marks that the
element continues below.
bodyClass
Type
string
Default
(empty)
Class attribute of the <body> inside the preview frame. Use it
when your stylesheet expects a class on the body, for example a theme
or a scope class.
css
Type
array
Default
[]
Stylesheets to load inside the frame, as EXT: paths or public
URLs. Usually the CSS bundle of your frontend build. Look's own small
stylesheet (scaling, fade-out) is always loaded first.
js
Type
array
Default
[]
JavaScript modules to load inside the frame, as EXT: paths or
public URLs. They are loaded as <script type="module"> and
only when the feature flagallowSiteScriptsis enabled. Without it the previews show the static markup with
CSS only.
Assets registered by the content
Templates and components inside the preview may register their own assets
with the standard Fluid view helpers <f:asset.css> and
<f:asset.script>. Look collects those while rendering the content and
puts them into the head of the preview frame. They never reach the backend
page, and they never leak into the preview of another content element.
Scripts registered this way follow the same rule as the js argument:
they load only when allowSiteScripts is enabled, and
they get the nonce of the backend request so the preview's Content Security
Policy accepts them.
When rendering fails
If the frontend markup cannot be rendered (a missing partial, a PHP error in
a view helper), Look shows a red callout in place of the preview instead of
breaking the page module. In development context, or with backend debugging
enabled, the callout contains the error message; in production it names only
the error code and the message goes to the TYPO3 log. Fix the template and
reload the page module; there is nothing to clear.
Tips for good previews
Render inside the frontend container
Put the element into the same wrapper markup as the frontend page
(content container, grid). Otherwise widths, gutters and backgrounds
look different from the website.
A form element with the site's containers and spacing: the preview
matches the website because it uses the same wrapper markup.
Choose one scale for the whole site
Set the scale once in the extension configuration
and leave the argument out of the templates. Editors get a consistent
zoom level across all element types.
Limit the height of long elements
A list or a slider with dozens of items makes the page module very long.
Give those element types a height, the fade-out tells editors the
element continues.
Keep hidden things hidden
The backend shows hidden relations by default. If your frontend hides
unpublished images or child records, make the preview do the same, for
example by resetting the visibility aspect of the TYPO3 context while
rendering the preview. Otherwise editors see a layout the website never
shows.
Configuration
Look works without any configuration. Two kinds of settings exist: defaults
for the appearance of the previews (extension configuration) and switches
that grant the previews additional capabilities (feature flags).
Open Admin Tools > Settings > Extension Configuration and choose
look. The values are used whenever the view helper is called
without the corresponding argument.
Default scale and default maximum height in the extension configuration.
Factor all previews are scaled down with unless a template sets its
own scale. 0.5 shows the frontend
at half size, 0.6 at 60 percent, 1 at full size.
A good starting point is the width of your page module divided by the
width of your frontend layout. With a 1200 pixel wide frontend and a
page module column of about 700 pixels, 0.6 shows the whole
width of the site.
contentPreview.height
Type
positive integer
Default
0
Maximum height of all previews in pixels unless a template sets its
own height. Taller elements are cut off
with a fade-out. 0 means no limit.
The same values can be set in config/system/settings.php or
additional.php, for example in a deployment:
The preview frame is locked down by default (see Security). Two
feature flags open it up step by step, a third adds an editing shortcut. All
are off unless you enable them, and enabling a flag always means giving
the preview an additional capability.
Set them in config/system/settings.php or additional.php:
Loads the JavaScript of your site inside the previews: the modules of
the js argument and scripts registered with
<f:asset.script>.
Off: the previews show the static markup with CSS only. Sliders
show all slides, masonry grids fall back to their CSS layout, tabs
show their first pane. Look's own small script for the frame height
still runs.
On: the site scripts run inside the frame, so interactive elements
look like on the website. The scripts run in the isolated frame and
cannot reach the backend, but they do execute, so only enable the
flag for a frontend build you trust.
look.contentPreview.allowMedia
Default
false
Loads video and audio files and embedded players inside the previews.
Off: the preview document carries a Content Security Policy that
blocks media files and embedded frames (YouTube, Vimeo, ...), so opening
the page module does not download videos. Videos show as striped
placeholder boxes in the size the layout reserves for them (Firefox
and Safari keep their play button on top of the box).
A content element with a video while media are blocked: the layout
is complete, the video area is a placeholder.
On: the media files load and the first frame of a video is shown;
embedded players load as far as the backend Content Security Policy
allows their host. Autoplay still does not happen inside the page
module, the TYPO3 backend does not grant that permission to embedded
frames.
Edit overlay
look.contentPreview.editOverlay
Default
false
Turns every preview into a shortcut for editing. Editors who hover a
preview see a pencil icon in a circle, the same icon as in the element
header, and a click behaves exactly like that header button: on TYPO3
14.3 and later the contextual edit panel slides in from the side, on
older versions, which do not know the panel, the classic edit form opens. Editors who switched the
contextual panel off in their user settings get the classic form here
as well.
Hovering a preview with the edit overlay enabled.
The overlay only appears for users who are allowed to edit the element.
Look applies the same rules as the edit button in the element header:
administrators always see it; everybody else needs modify access to the
table, content edit permission on the page, a page that is not locked for
editing, and edit access to the record (table, language, record lock).
Users without these rights get the plain preview, so nobody is offered an
action they cannot perform.
Note
The record check relies on BackendUserAuthentication::checkRecordEditAccess()
(TYPO3 14) respectively recordEditAccessInternals() (TYPO3 13).
Both are marked @internal by the TYPO3 core; they are the only
way to apply exactly the rules the header button applies. Look's unit
tests pin their behaviour, so a change in a core release is noticed.
Look finds the record on its own from the template variables: the
data object of a Content Blocks preview or the record
array of a classic preview template. Nothing has to be passed to the view
helper.
After changing the configuration
Extension configuration and feature flags are read on every request, the
previews themselves are rendered on every load of the page module. Reload
the page module after a change; no cache needs to be flushed.
Security
A preview shows content that editors wrote, rendered with templates and
scripts of the frontend, inside the backend of the site. Look treats that
content as untrusted and isolates every preview as far as browsers allow.
This chapter explains what is in place and what it means for you.
Every preview is an <iframe> with the sandbox attribute set
to allow-scripts and nothing else. Browsers then give the frame an
opaque origin: the content behaves as if it came from an unknown, foreign
website.
Concretely, content inside a preview
cannot access the backend: no access to the TYPO3 backend document,
the editor's session cookie, local storage or session storage;
cannot navigate or open windows: no links to follow, no popups, no
redirects of the backend;
cannot submit forms: a contact form in the preview is just markup;
cannot show dialogs: no alert(), no download prompts;
cannot be clicked: the frame ignores pointer events, the editor's
clicks go to the page module controls as usual.
The referrerpolicy is no-referrer, so requests from the frame
carry no backend URL.
Scripts are limited by a Content Security Policy
Scripts may run inside the frame, otherwise Look could not report the
content height to the page module. Which scripts run is decided by a Content
Security Policy in the preview document:
script-src 'nonce-<nonce of the backend request>' 'strict-dynamic'
Copied!
Only script tags that Look itself writes into the document carry that nonce:
its own height script and, with allowSiteScripts,
the scripts of your frontend build. A <script> that arrives inside
the content, for example through an unsafe rich text field, has no nonce and
is refused by the browser. 'strict-dynamic' lets the trusted scripts
import their own modules.
Media are blocked by default
Unless allowMedia is enabled, the same policy
also contains media-src 'none'; frame-src 'none'. Video and audio
files are neither downloaded nor played while the page module is open, and
embedded players (YouTube, Vimeo and other iframes) are not loaded either;
videos appear as striped placeholder boxes. Besides bandwidth this avoids a
page module full of playing videos.
The preview document also inherits the Content Security Policy of the TYPO3
backend. Its default only allows assets from the backend's own host, so
external fonts, libraries or images need an explicit extension of that
policy, see Assets from other hosts do not load.
No permissions
Camera, microphone, geolocation, fullscreen, autoplay and the other browser
permissions are not available to the frame. The TYPO3 backend does not grant
them to embedded frames, and the opaque origin of the sandbox denies the rest.
What this means for you
Enable feature flags deliberately
The defaults give previews no capabilities beyond CSS. Enabling
allowSiteScripts runs your frontend
build inside the frame. It stays isolated from the backend, but review
what the build does (tracking, external requests) before enabling it.
Web fonts need a CORS header
The opaque origin makes web fonts and script modules cross-origin
requests. Look's own script is a classic script and works without any
server configuration, but your frontend fonts only load if the server
answers with Access-Control-Allow-Origin: * for their path, see
If your frontend uses web fonts. The header is standard practice for public
static files and exposes nothing the files did not expose before.
Some frontend techniques need adjustments
External SVG sprites (<use href="...svg#icon">) cannot load inside
an opaque origin, see SVG icons are missing. Scripts running in the
frame (with allowSiteScripts) have no
sessionStorage or localStorage and cannot autoplay media;
guard such calls in your frontend code as you would for private browsing
modes.
Known problems and how to solve
Most problems come from the isolation of the preview frame. The frame has an
opaque origin, which changes how browsers treat a few frontend techniques.
This chapter lists the symptoms and the fixes.
The previews stay empty on a password-protected site
Symptom: the website asks for a user name and password before it shows
anything (HTTP Basic Auth, common on staging and preview servers). In the
page module every Look preview is an empty box, about 150 pixels high, with
no styling and no images. The browser console reports 401 errors for the
files inside the frame.
Cause: this is intended. The preview frame is deliberately isolated from
the backend, see Security. The browser treats it like a page from an
unknown website: it has no login of any kind, neither your TYPO3 session nor
the password you typed into the browser's prompt. Every stylesheet, script and
image the frame requests is therefore refused by the server, and browsers do
not show a password prompt for such requests.
It is the same wall that protects your session. Nothing rendered inside a
preview can reach the backend, and in return the preview cannot borrow the
backend's credentials. Look has no switch to open that wall, because opening
it would give preview content the same access to the backend that you have.
What you can do: nothing inside TYPO3, this is a property of the server
setup. The previews work on every installation that is reachable without a
password prompt, which is the normal case for a live site.
In theory the server could be configured to deliver the static files the
previews need (stylesheets, scripts, images, fonts) without asking for the
password, while the pages themselves stay protected. Be aware of what that
means: depending on how it is done, those files become publicly readable
for anyone who knows or guesses their address, including uploaded images
and documents. Whether that is acceptable has to be decided per project.
Look neither recommends nor documents such a setup; if it is done, it is
entirely the responsibility of the people operating the server.
Assets from other hosts do not load
Symptom: web fonts from Google Fonts, a library from a CDN or images from
an external server are missing in the preview, while they work on the
website. The console reports a Content Security Policy violation, not a
CORS error.
Cause: the preview document inherits the Content Security Policy of the
TYPO3 backend, which by default only allows assets from the backend's own
host. Adding a CORS header does not help here, the browser refuses the
request before it is sent.
Fix: serve the assets from your own host, or extend the backend policy
for the hosts you trust with a Configuration/ContentSecurityPolicies.php
in your site package:
<?phpuseTYPO3\CMS\Core\Security\ContentSecurityPolicy\Directive;
useTYPO3\CMS\Core\Security\ContentSecurityPolicy\Mutation;
useTYPO3\CMS\Core\Security\ContentSecurityPolicy\MutationCollection;
useTYPO3\CMS\Core\Security\ContentSecurityPolicy\MutationMode;
useTYPO3\CMS\Core\Security\ContentSecurityPolicy\Scope;
useTYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue;
useTYPO3\CMS\Core\Type\Map;
return Map::fromEntries([
Scope::backend(),
new MutationCollection(
new Mutation(MutationMode::Extend, Directive::FontSrc, new UriValue('https://fonts.gstatic.com')),
new Mutation(MutationMode::Extend, Directive::StyleSrc, new UriValue('https://fonts.googleapis.com')),
),
]);
Symptom: the preview uses fallback fonts, or with
allowSiteScripts the site scripts do not
run. The browser console inside the frame reports a CORS error.
Cause: web fonts and JavaScript modules are loaded as cross-origin
requests from the frame. The web server does not send
Access-Control-Allow-Origin: * for them. Look's own script is not
affected, it is a classic script.
Symptom: icons referenced as an external SVG sprite are blank. The console
says "Unsafe attempt to load URL ... from frame with URL about:srcdoc".
Cause:<svg><use href="/icons.svg#play"> may only load files from
the same origin, and the frame has none.
Fix: inline the SVG when rendering for the preview. A small view helper
that reads the icon file and returns its markup does the job. Detect the
preview context in your templates, for example with a flag your preview
template sets, and switch between the sprite reference (frontend) and the
inline markup (preview):
Symptom: the preview shows broken images or an error about a processed
file that does not exist.
Cause: backend requests defer image processing to a later request. A
frontend template that expects the processed file immediately (for example a
custom picture renderer) does not get it.
Fix: set the fileProcessing aspect of the TYPO3 context to
non-deferred (new FileProcessingAspect(false)) while rendering the
preview, in the same wrapper that handles the visibility aspect.
A red callout instead of the preview
Symptom: the page module shows "Preview could not be rendered" with an
error message and a code.
Cause: rendering the frontend markup threw an exception.
Fix: in development context (or with backend debugging enabled) the
callout names the problem, usually a missing partial, a wrong argument or a
PHP error in a view helper; in production it shows only the error code and
the details go to the TYPO3 log. Correct the template and reload the page
module.
Nothing works in the standalone Install Tool
The previews need the nonce of a backend request. The standalone Install Tool
(/typo3/install.php) has none and does not render page module
previews, which is expected.
Sitemap
.. sitemap::
Reference to the headline
Copy and freely share the link
This link target has no permanent anchor assigned.The link below can be used, but is prone to change if the page gets moved.