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
Here's what my project directory looks like:
Now let's tie 'em together! Pop into index.php
, and add a point of entry. I chose:
<div id="svelte-app"></div>
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;
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>
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/:
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(),
Now, with your terminal still in the svelte
directory, you can run the familiar
> npm run dev
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!
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)
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!
Have you tried doing this with Svelte kit?
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.
gulp>>