Laravel Svelte Direct: Seamless Svelte Components In Your Laravel Blade Templates

Nick Poulos
4 min readMay 22, 2021

--

Modern JavaScript has been a gift and a curse. An amazing gift for developing front ends, plus a whole lot of cursing trying to get it all configured and setup.

Things that used to be very simple became increasingly complex overnight. With build tools, polyfills, SSR, code-splitting, and everything else, it can get overwhelming quick.

There have been several awesome attempts to get the best of both worlds, especially within the Laravel community. We have amazing projects like Livewire and Alpine.js. Then you have projects like Inertia and Airewire that provide some kind of glue between your JS frontend and PHP backend.

Lately I have really taken a liking to Svelte, a different take on the typical React/Vue style application. It was refreshing to get declarative, reactive, single file components, without all the boilerplate.

Svelte also has some other very interesting properties…mainly that it is more a compiler/language rather than a true framework. And because of that, it can actually compile to different targets. More on that later.

That is all fine and dandy, but coming from PHP & Laravel, I still want my Blade templates and server side rendering (ya know the old school way).

Normally in this situation, Laravel is just there to serve the shell of the DOM, and then have Svelte/Vue/React take over your entire body tag, or very large chunks of your DOM.

What if instead, we could just sprinkle our Svelte components from within Blade itself when necessary? What if we didn’t have to worry about which components were on the page, about importing them, code-splitting, or any of that?

That’s where this two-package project comes in. A custom Laravel Mix extension along with a Blade precompiler/directive that I have named Laravel Svelte Direct.

Svelte Direct allows us to:

  • Write our Svelte components like usual
  • Easily compile each component into its own bite-sized JS file using Laravel Mix
  • Use our components inside Blade templates like regular HTML
  • Svelte Direct automatically loads the proper component JS file in your head tag (or wherever you want)

Ok, enough talk, let’s install.

Install & Configure Svelte Direct Mix Extension

npm install laravel-svelte-direct-mix

Once installed, let’s add Svelte Direct to our Laravel Mix config file (webpack.mix.js). Pass in your Svelte components folder and it will recursively find all .svelte files, and compile each one separately into it’s own JS file inside your output folder.

The third parameter options object contains the default settings for Svelte Direct, and is not required unless you want to use custom settings.

Default configuration for Svelte Direct Mix Extension

When componentMode is false, the Svelte compiler will targetcustomElementmode. See Appendix.

By settingloaderOptions you can pass in the specific options for the https://github.com/sveltejs/svelte-loader used under the hood.

Install Laravel Svelte Direct

composer require nickpoulos/laravel-svelte-direct

Once installed, let’s find our ‘main’ Blade component or layout that holds our <head> tag, and let Svelte Direct know where we want our compiled JS loaded. The custom blade directive @sveltedirect handles that for us and will automatically load the correct JS files.

Add the custom blade directive to place our <script> tags

Add Options To Svelte Component

Since Svelte already has built in support for customElement it also provides mechanisms to tell the compiler what actual HTML tag to use to represent our component. These tags must have a - hyphenated name, as seen above with <flash-message> and <app-header> .

Let’s find our FlashMessage.svelte file and add the proper lines.

<!-- svelte-ignore missing-custom-element-compile-options -->
<svelte:options tag="flash-message" />

*These two lines are all documented parts of Svelte, and is not custom syntax created by this package.*

Compile Laravel Mix

Finally, we just have to compile our assets using Laravel Mix, and we are done.

npm run dev

Now, when you load your view above, the Blade template will be scanned for our Svelte component tags, and when found, the correct component sized Js file will be automatically loaded in the header for us!

By using DOM events and other standard intra-component communication methods, we can tie our components together using vanilla JS or Alpine right there in our Blade template as well.

Appendix

As mentioned, Svelte can compile its components to different targets. One of those is for WebComponents. It allows you to compile your Svelte components into custom HTML tags. This has been a hotly debated topic within the Svelte and larger front end communities. I won’t get into the details of the debate, but I will just say that WebComponents come with certain caveats at the moment.

Because of that, by default Svelte Direct will use an alternative method that works similarly, but does not include the shortcomings that traditional WebComponents currently have.

If you would like to try using more traditional WebComponents in this setup, simply set componentMode to false, and your Svelte components will be compiled using the customElement directive in the Svelte compiler.

For more information see:

--

--

Nick Poulos
Nick Poulos

No responses yet