Skip to content

Setting up Symfony and Svelte

Note: I wrote this draft quite awhile ago. Rather than leave it in a draft forever, I’m going to publish the incomplete version.

A few weeks ago I heard that Svelte 3 had been released. After poking around with it, Svelte is quickly becoming my favorite JavaScript framework. While I was playing around I setup Svelte and Symfony to work together. If you aren’t interested in reading a post and just want to see the code, it’s in voldemortensen/symfony-svelte-example on my GitHub.

The rest of this post assumes that you already have composer and npm (or yarn) installed.

Let’s use symfony/website-skeleton to get started. In terminal:

composer create-project symfony/website-skeleton symfony-svelte-example && cd symfony-svelte-example

For the Svelte bits let’s use Encore to configure Webpack. Encore is a great tool for using Webpack to build assets for use with Symfony. In terminal:

composer require symfony/webpack-encore-bundle

then

npm i

then

npm i --save-dev svelte-loader svelte


At this point everything we need to install is installed. Now let’s get the config setup. In webpack.config.js add this after .setOutputPath and .setPublicPath:

.addLoader({
    test: /\.svelte$/,
    loader: 'svelte-loader',
})

and this at the end of the file after removing the default module.exports line:

let config = Encore.getWebpackConfig();
config.resolve.mainFields = ['svelte', 'browser', 'module', 'main'];
config.resolve.extensions = ['.mjs', '.js', '.svelte'];

let svelte = config.module.rules.pop();
config.module.rules.unshift(svelte);

module.exports = config;

With all the configuration setup, let’s get to the code. We need to get a route setup. In terminal:

php bin/console make:controller

This will prompt you to give a name for the controller. Personally, I use DefaultController for /.

In src/Controller/DefaultController.php find the line with @Route("/default", name="default") and change it to @Route("/", name="default).

In templates/default/index.html.twig, delete everything and replace it with this:

{% extends 'base.html.twig' %}

{% block title %}Hello Symfony + Svelte!{% endblock %}

{% block javascripts %}
    {{ encore_entry_script_tags('app') }}
{% endblock %}

{% block stylesheets %}
    {{ encore_entry_link_tags('app') }}
{% endblock %}

{% block body %}
{% endblock %}

In assets/js/app.js, delete the console.log line and add this at the end of the file:

import App from './App.svelte';

const app = new App({
    target: document.body,
});

And for the final bit, create assets/js/App.svelte and add this:

<h1>Symfony + Svelte = <3</h1>

<style>
    h1 {
        text-align: center;
        color: #D26D26;
    }
</style>

<script>
    import { onMount } from 'svelte';

    onMount(() => {
        console.log(`Hello, Symfony + Svelte!`);
    });
</script>
Published inCodejavascriptphp