Engineering PHP Svelte Laravel Frontend JavaScript

Integrate Svelte with Laravel Blade (without inertia): A Step-by-Step Guide


Laravel’s Blade is a powerful templating engine for building dynamic web applications. Svelte, on the other hand, is a cutting-edge JavaScript framework known for its reactive user interfaces and compile-time optimizations. In this step-by-step guide, we’ll walk you through integrating Svelte components into a Laravel Blade application and passing props effectively from Blade templates to Svelte components. This integration allows you to leverage the power of both Laravel and Svelte to create high-performing, SEO-friendly web applications.

Prerequisites

Before we dive in, make sure you have the following:

  • An existing Laravel application (you can create one quickly using composer create-project laravel/laravel laravel-svelte)
  • A basic understanding of Laravel, Svelte, and Vite

Step 1: Adding Svelte to Your Laravel Project

To start, we need to add Svelte and its dependencies to our Laravel project. Run the following command in your terminal:

pnpm add svelte svelte-preprocess typescript

This command installs Svelte, svelte-preprocess (for handling preprocessors like PostCSS), and TypeScript for enhanced development.

Next, update your package.json file to include "type": "module". This enables ES Module support, which is essential for modern JavaScript development.

Step 2: Configuring Vite for Laravel and Svelte

Vite is a modern build tool that provides a fast and efficient development experience. We need to configure it to handle both Laravel Blade and Svelte files. Open your vite.config.ts file and modify it as follows:

import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";
import { svelte } from "@sveltejs/vite-plugin-svelte";

export default defineConfig({
  plugins: [
    laravel.default([
      "resources/css/app.css",
      // this is where we'll import and mount our svelte components in
      "resources/js/main.ts", 
    ]),
    svelte(),
  ],
});

This configuration ensures that Vite can process both your Laravel Blade templates and your Svelte components.

Step 3: Mounting a Basic Svelte Component

Now, let’s mount a simple Svelte component in your Laravel application. First, create a Svelte component (e.g., resources/js/components/Navbar.svelte). Then, import and initialize it in your main.ts file:

import Navbar from "./components/Navbar.svelte";

new Navbar({
  target: document.getElementById("navbar"),
});

This code snippet mounts the Navbar component onto an HTML element with the ID “navbar” in your Blade template.

Step 4: Passing Props from Blade to Svelte

Suppose our Svelte Component looked like this:

<script lang="ts">
    export let articleTitle: string;
    export let articleBody: string;

    function removeScriptTags(html: string) {
        return html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
    }
</script>

<div class="card">
    <div class="card-body">
        <h1 class="card-title">{articleTitle}</h1>
        <p class="card-text">{@html removeScriptTags(articleBody)}</p>
    </div>
</div>

This component accepts two props, articleTitle and articleBody, to render an article dynamically while safeguarding against script injection.

But how do we send data to display? Passing props from Laravel Blade to Svelte requires a slightly different approach. Since Svelte, unlike Vue or React, doesn’t work natively in Blade, we’ll use HTML data-* attributes as a bridge.

Blade Template Example:

<div class="prose" id="article" data-title="{{ $page->title }}" data-body="{{ $page->content }}"></div>

In our aforementioned main.ts file, you can then extract these data attributes and pass them as props to your Svelte component:

import Article from "./components/Article.svelte";

const article = document.getElementById("article");
const title = article?.dataset.title;
const body = article?.dataset.body;

(() => {
  new Article({
    target: article,
    props: {
      articleTitle: title,
      articleBody: body,
    },
  });

  // Remove data attributes for cleaner HTML (optional)
  article?.removeAttribute("data-title");
  article?.removeAttribute("data-body");
})();

This approach ensures clean, semantic HTML while enabling dynamic content through props.

Why Integrate Svelte with Laravel?

Combining Svelte with Laravel offers several key benefits:

  • Improved Performance: Svelte’s compile-time optimizations result in smaller bundle sizes and faster loading times, enhancing the user experience.
  • Enhanced Reactivity: Svelte’s reactive programming model makes it easy to build dynamic and interactive user interfaces.
  • Maintainability: Svelte’s component-based architecture promotes code reusability and maintainability, making it easier to manage complex applications.

Conclusion

By following this guide, you can successfully integrate Svelte components into your Laravel Blade projects. This powerful combination allows you to build dynamic, high-performing web applications that are also optimized for search engines. Remember to continuously monitor your website’s performance and make adjustments as needed to achieve the best possible results.