Jump to navigation

By default, when Fractal renders a component, it does so without wrapping it in any ‘page’ structure markup.

That means that it is effectively an HTML fragment, as opposed to an HTML page. As a result, your components will appear unstyled; Fractal does not automatically insert any styles or behaviour into the rendered markup.

In order to faithfully render a component in the same way as it will look in your live site, Fractal supports the use of preview layouts. These are used when rendering component previews, and allow you to ‘wrap’ your component in some page markup so you can do things like link to your stylesheets, JavaScript files and so on, just as you would in your site proper.

Creating a preview layout

Preview layouts are just another component, and so must reside in your component directory. Like any other components, preview layouts can be hidden by prefixing their name with an underscore if you don’t want them to show up in listings or navigation.

For example, we could create a preview layout called _preview.hbs in the root our components directory:

├── components
│   └── _preview.hbs

The contents of that file might look something like this:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <link media="all" rel="stylesheet" href="{{ path '/example.css' }}">
    <title>Preview Layout</title>
</head>
<body>

{{{ yield }}}

</body>
</html>

Note the {{{ yield }}} placeholder. That is where the rendered component will be included into the final generated markup.

The triple {{{ mustache tags around the yield placeholder are required so that handlebars does not automatically escape the rendered HTML of the component - if you are using a different templating language then you may need a different syntax to prevent the template engine from escaping the output.

We can also see that the layout is including a stylesheet. The href attribute value of the stylesheet link element is being generated by a Handlebars helper - {{ path '/example.css' }}. For details on this and how to link to static assets such as CSS, JavaScript files and images from your preview layouts and view templates, see the documentation on static assets.

You can put as much or as little as you want into your preview layouts, but it’s recommended that they match up as much as possible to the ‘real’ template that your components will be rendered in when used in your site.

Specifying a preview layout for a component

You can specify a default preview layout to use on a global basis or on a component-by-component basis (allowing different layouts for different use-cases).

You can also take advantage of the configuration cascade and specify preview layouts on a per-collection basis as the default for all components in that collection.

In all cases, the preview layout must be referenced by the handle of the layout component.

Global (default) preview layout

You can set the default preview layout on your Fractal instance using the @handle reference for the chosen layout.

fractal.components.set('default.preview', '@preview');

In a parent collection’s configuration file

All components within this collection will have this set as their default preview layout unless the specifically override it.

// patterns.config.json
{
    "preview": "@preview"
}

In a component’s configuration file

Setting it directly in a component’s config file will override any defaults set further upstream.

// component.config.json
{
    "preview": "@preview"
}

Context in preview layouts

Preview layouts are just components and can have their own configuration files associated with them, just like any other components. That means you can specify context data for the layout in the configuration file, and you will be able to access it from within the layout.

You will not be able to access the layout’s context data from within the component that is being rendered. The component is not included as a partial in the layout, but rather rendered first and then passed in as a property on the layout’s context data.

The _target property

Preview layouts, when rendered as a layout and not as a component on their own, will have access to a special context property called _target. This is a JSON representation of whichever component or variant is being rendered within the layout.

Having access to this means that you can do things like dynamically set the page title of your layout based on the component being rendered. For instance, in your layout template you could do:

<head>
<title>{{ _target.label }} | My Component Library</title>
</head>

Your page title would then match the component being rendered.

Preview rendering details

It may be useful to understand the exact rendering order when a preview layout is used. The rendering works as follows:

  1. The component view is rendered, using its own set of context data.
  2. The rendered output is assigned to a special property, yield, which is attached to the preview layout’s context data.
  3. A JSON representation of the component being rendered is assigned to the _target property of the layout’s context data.
  4. The layout view file is rendered using its own preview context data, complete with the additional yield and _target properties.