Laravel Components and Component Libraries

— 4 minute read

If you use a component library you might find some disconnect between them and how they're used on a project website. I have a primer about using the component library Fractal and your website. This describes syncing your CSS, JS and assets from the component library to your project website. But what about the actual components themselves?


Laravel uses the templating engine Blade and has supported components for a while. Since version 7, they now support a more HTML-friendly syntax. Previously you would use the @component syntax;

@component('my-component')
Your slot content goes here.
@endcomponent

But you can now use them like a custom HTML element, just with an <x-> prefix;

<x-my-component>
Your slot content goes here.
</x-my-component>

They are a lot more powerful than this, with support for a component Class, attributes and properties. But I want to concentrate on their mirroring of component library use.


Fractal permalink

The component library I have been using is Fractal. Out of the box Fractal uses Handlebars to render view templates, but they do support different template engines. Unfortunately, Laravel Blade is written in PHP, so we can't use it here*.

I have stucked with the default Handlebars template engine. Below is an example of a component library “molecule” which is combining a couple of smaller components in to a useful re-usable block.

<div class="blurb blurb--with-social">
{{ render '@avatar' avatar }}

<div class="blurb__content">
{{ content }}
</div>

{{ render '@social' }}
</div>

Converting to Blade permalink

Moving from Handlebar template engine to Blade isn't that difficult. Below is an example of the conversion, including properties being passed through. Instead of using Handlebar's render @component you use the Blade's <x-component> syntax.

<div class="blurb blurb--with-social">
<x-avatar :avatar="$avatar" />

<div class="blurb__content">
{{ $content }}
</div>

<x-social />
</div>

You can organise the Blade components in the same way you organise them in your component library. Using the “Atomic Design” principle naming convention; atoms, molecules and organisms and structuring them with folders, your Blade setup might look like this;

components/atoms/button.blade.php
components/atoms/social.blade.php
components/atoms/xxx.blade.php

components/molecules/blurb.blade.php
components/molecules/xxx.blade.php

components/organisms/header.blade.php
components/organisms/footer.blade.php
components/organisms/xxx.blade.php

Then you can use them like this;

<div class="blurb blurb--with-social">
<x-atoms.avatar :avatar="$avatar" />

<div class="blurb__content">
{{ $content }}
</div>

<x-atoms.social />
</div>

And to integrate that in to your page template;

<x-organisms.header />
<x-molecules.blurb />
<x-organisms.footer />

This will give you a one-to-one relationship between your component library and your website project. Although they're not completely in sync, your HTML should change very rarely.


* There is a port of Laravel Blade to JavaScript but I haven't used it, so I can't comment how useful it is.