Using Fractal with Craft CMS

Here at Mud we're always looking at the latest tools and technologies to help improve our development process. Fractal by Clearleft is a recently-discovered tool that helps us build and document web component libraries and use them in our projects. We've spent some time working out how to use it with another one of our favourite tools, Craft CMS.

Component libraries and component based development have seen a big increase in popularity recently. Used as a way of designing and building sites in a modular fashion, it helps break up parts of a site into smaller, reusable elements. So why Fractal?

Powerful component libraries & styleguides that fit the way you work.

With Fractal we can assemble, preview and document the components being built for each of our projects. These components can then be assembled into larger components or entire pages ready for integration into our sites or apps.

Fractal gives us complete freedom with the choice of template language for components, so by using a node implementation of Twig we can use them directly in our Craft templates without any further modifications.

The Fractal web UI allows us to browse the component library through a local web server and has a powerful API and CLI that integrates nicely with our task runners.

You can take a look at the Fractal UI for this site here.

How we use it with Craft

Let's take an author.twig component. It contains some markup and a few variables -

<div class="c-author flex items-center">
<div class="md:block md:mr-1">
<img src="{{ image.url }}" class="lazyload" data-src="{{ image.url }}" alt="{{ image.alt }}" width="{{ image.width }}" height="{{ image.height }}" />
</div>
<dl class="p-0 m-0">
<dt>Author:</dt>
<dd class="m-0 mb-0-25 p-0">{{ name }}</dd>
<dt>Job Title:</dt>
<dd class="m-0 p-0">{{ position }}</dd>
</dl>
</div>

The key to using Fractal with Craft effectively is how data is passed into our components. We need it to work when components are in development and then also when the site is fully integrated with the CMS (which often happen at different points during the project).

In Fractal the component preview data can be hardcoded or generated from a service or an API call. For each of our components we can create a config.js file containing the data object -

module.exports = {
status: 'ready',
context: {
name: 'Matt Powell',
position: 'Founder & Creative Director',
image: {
url: 'https://picsum.photos/g/60/60/...',
alt: 'Placeholder Image',
width: '60',
height: '60'
}
}
}

Using our task runner, we can move the production-ready components into our Craft templates directory. During the build task, a JSON file containing the handle and relative paths for our components is generated.

{
"@author": "_partials/04-components/author/author.twig"
}

By adding a plugin that hooks into the template loading within Craft, we can use @handle in our page templates to reference the components listed in the JSON file.

if (strpos($name, '@') === 0)
{
$mappingPath = CRAFT_BASE_PATH. '/components-map.json';
if (is_readable($mappingPath))
{
$mappings = json_decode(file_get_contents($mappingPath));
if ($mappings->$name) {
if (strpos($mappings->$name, '/') !== 0) {
$template = realpath(CRAFT_BASE_PATH) . '/templates/' . $mappings->$name;
} else {
$template = $mappings->$name;
}
}
}
else
{
throw new Exception(Craft::t('Could not read Fractal mappings file', array('path' => CRAFT_BASE_PATH)));
}
}

Fractal component loader plugin for Craft CMS - Version 2, Version 3 (Credit allmarkedup).

With the plugin installed, we can include the component in our Craft page template and pass in the required data that now comes from the CMS -

{% include '@author' with {
image: {
url: author.image[0].url,
alt: author.image[0].title,
width: author.image[0].width,
height: author.image[0].height
},
name: author.name,
position: author.position
} %}

Now we can continue working on a site's components using the Fractal UI, and automatically move them over into the Craft templates when ready!

Click here to see our Mud frontend starter kit with Fractal and Craft 3.