DEV Community

Cover image for How to: embed a Svelte app within a PHP application, with Live Reload
Anthony Gushu
Anthony Gushu

Posted on

How to: embed a Svelte app within a PHP application, with Live Reload

Woah it's my first DEV article!

Alright, so at my day job I inherited a system built on PHP. The DOM is almost completely rendered in PHP which annoys the hell out of me -- I've been dreaming sweet thoughts of Svelte.

Wanting to make the switch, I often thought about redoing the whole system using fetch() requests in Svelte with a request-response scheme in PHP, but there's so much code that a Big Bang-style switch isn't feasible. Therefore, I needed to plant a seed that would eventually grow into something large and beautiful (perhaps a tea tree, or a napa cabbage).

So this morning I decided fuck it, it's time to put Svelte's clean little hands on some PHP-rendered DOM. And spoiler: it's pretty painless.

Slap in Svelte

You've first got to choose a sub-project to use Svelte on within your existing PHP project.

Navigate to that directory of your existing project in the terminal and drop in our old friend:



 > npx degit sveltejs/template svelte
 > cd svelte
 > npm install


Enter fullscreen mode Exit fullscreen mode

Here's what my project directory looks like:

'svelte' project folder below a folder containing 'index.php'

Now let's tie 'em together! Pop into index.php, and add a point of entry. I chose:



<div id="svelte-app"></div>


Enter fullscreen mode Exit fullscreen mode

On the Svelte end, match this entry point as your target in main.js:



import App from './App.svelte';

const app = new App({
  target: document.getElementById('svelte-app'),
  props: {
    name: 'world',
  },
});

export default app;


Enter fullscreen mode Exit fullscreen mode

Now we essentially have to recreate the core parts of
svelte/public/index.html.

We're going to link the Svelte-generated script and stylesheets. This part can be done two ways depending on your existing PHP project. If you have direct access to the html head, then just copy and paste the link and script elements from the head of index.html to the PHP file's head, with path adjustments to reach the same files they reference.

In my case, I don't have a direct access method to augment scripts/stylesheets to the head in this PHP project. While I could make a method for that, I kinda just felt like doing it in Javascript. So I added this into the PHP file:



<script>
    const svelte_script = document.createElement('script');
    svelte_script.type = 'text/javascript';
    svelte_script.defer = true;
    svelte_script.src = '../svelte/public/build/bundle.js';
    document.head.appendChild(svelte_script);

    const svelte_global_stylesheet = document.createElement('link');
    svelte_global_stylesheet.rel = 'stylesheet';
    svelte_global_stylesheet.href = '../svelte/public/global.css';
    document.head.appendChild(svelte_global_stylesheet);

    const svelte_compiled_stylesheet = document.createElement('link');
    svelte_compiled_stylesheet.rel = 'stylesheet';
    svelte_compiled_stylesheet.href = '../svelte/public/build/bundle.css';
    document.head.appendChild(svelte_compiled_stylesheet);
</script>


Enter fullscreen mode Exit fullscreen mode

Do whichever floats your pontoon, until someone argues below that the Javascript way is perhaps less efficient and makes us all feel bad for doing something that feels cool.

Now this will work if you do npm run build from the svelte folder with MAMP or whatever Apache server you have running for the PHP part, but dammit we want live-reload and automation!

Live Reload

This is the perfect point to add live-reload to your PHP server if you haven't already. If you're using VSCode, add Live Server and its browser extension.

Configure the browser extension with the virtual host name set in, say, MAMP as the actual server address. Then the server that this plugin runs, usually http://127.0.0.1:5500/:

Live Server browser extension visual

Follow the plugin's guide, hit Go Live in index.php and you should be PHP-live-reloading. But maybe wait to test this until after the next step so to avoid some Node server-Apache server fighting if you've got Svelte's localhost running too.

We only need Rollup in Svelte to be responsible for watching Svelte file changes and compiling those changes. To make this happen, we can delete the following lines from the rollup.config.js:



// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),


Enter fullscreen mode Exit fullscreen mode

Now, with your terminal still in the svelte directory, you can run the familiar



> npm run dev


Enter fullscreen mode Exit fullscreen mode

Now Rollup will notice changes to your Svelte files, and auto-recompile like normal. Live Server will then notice a change to the compiled Svelte files referenced in your PHP application and reload your PHP page in the browser automatically!

You can get rid of favicon.png and index.html from the Svelte public folder, too.

Look at that!

Svelte app embedded in a PHP app!

There's a whole number of ways to pass data between your PHP backend and Svelte interface, so I might turn this into a series the more I dive into the possibilities!

Top comments (4)

Collapse
 
anthonygushu profile image
Anthony Gushu • Edited

This can get a little wonky working with some npm-imported components. After importing the date-range-input component, I got a few Apache errors about too many files on the server and unknown errors about connecting to the SQL database(?). Those get fixed by saving in different files/restarting npm run dev. The component's CSS was 404'd too, although this component has a unique way of handling CSS.

So this is definitely experimental when it comes to using third party libraries/components, but otherwise it's worked like a breeze!

Collapse
 
jonkkillian profile image
Jon Kurtis ⚡

Have you tried doing this with Svelte kit?

Collapse
 
anthonygushu profile image
Anthony Gushu

I have not, but I'd imagine you could get a pleasant multi-page setup with SvelteKit mounted at an element in your PHP app in SPA mode, though there may be some caveats. Using the static adapter could be troublesome in that your SvelteKit app would take you out of your PHP context, unless you mount it inside an iFrame.

Collapse
 
0x11dfe profile image
Tesla

gulp>>