2020-09-12 18:00 | development

Converting a Traditional Website To An SPA

I re-wrote my website in Vue, after having used it for over a year as part of a Saas project. We’re still in the process of porting the frontend to Vue (from a traditional website), and I wanted to see what a pure-build Vue could do.

Vue is great fun to work with. It feels rapid to develop with, and like any of the reactive frameworks, it takes a lot of boilerplate code away so you can focus on the good stuff. Bundling SASS rules in with the component made the entire site an absolute breeze to build and maintain, and the entire codebase is very concise and predictable.

Deployment is easier too, though it’s easy to say that for a simple brochure site with a blog.

Whilst I really hope this is where the web is going, it’s not without its issues, one of which is probably no surprise..

Search Engine Optimisation

Search engines are still in their infancy when it comes to executing Javascript and indexing the results. As optimistic as Google have been with their documentation around this, it’s not hard to find results where converting to an SPA was a disaster for search engine rankings. There are a couple solutions:


This involves adding a build step to your task runner to get a browser to visit each intended URL of the site, execute it, and compile a html page for each result. You then upload these static html files alongside your SPA, and update your sitemap to point to these static resources. For example:

  • /
  • /about
  • /blog
  • /blog/{slug}

The above are the standard links of the SPA, but the static resources are served as:

  • /
  • /about/
  • /blog/
  • /blog/{slug}/

Your sitemap then points to these files.

Note that if a user is taken to any of the static versions, they should not see any difference over the SPA. All your links throughout the page will seamlessly go to the SPA equivalent.


This is going to sound daft, but bear with me here.

This approach involves allowing your web server to execute the app, and serve the results. If that sounds like a traditional website to you, then yes, that’s exactly what it is.

It seems funny that React, Vue are are often promoted with claims of “you can do everything in the frontend”, but then to solve the rather key issue of SEO, we have to resort back to having the codebase executed on the server as per the traditional way.. this point actually stopped me working on the site for a few days due to the seemingly defeatist approach of it, but I cracked on regardless, and haven’t regretted it.

I cannot detail the in’s and out’s of this as it’s not the approach I’m using, but it seems light enough and fair enough, and definitely the approach if your web app is significant in complexity.

Plugin availability and Support

This is the part where it gets very risky, particularly if you are building this for a client. More often than not, I’m finding plugins (for React and Vue) which provide some excellent functionality, but which end up abandoned. When you see their issue tracker and the top post is “Is anyone still maintaining this?” It can be gut-wrenching especially if there’s not yet an alternative. React users should be in a better situation here due to how long the ecosystem has been available, but admittedly, this issue is the one that stopped me supporting React a number of years ago.

As much as I really, REALLY enjoy using Vue, if I was still freelancing there is no way I would suggest it for client work unless the contract involved ongoing maintenance, and the client was made well aware of this potential issue. Receiving a project which has been written elsewhere and finding out it cannot build due to outdated dependencies leads to a rather pessimistic conversation with a prospective client after no doubt a few optimistic ones.

You could be wondering what’s the point in converting my current site to an SPA, or writing my next project as an SPA? After all, a standard PHP installation is server-side anyway? I decided it was worth sticking with - the goals of my own website conversion was to make the site much faster, much easier to maintain, and much cheaper to host - the result is just static resources which can be deployed even on an AWS bucket, as opposed to PHP, Apache, and MySQL, for what is otherwise a small blog. I am happy with the decision, though there is a small trade-off - adding a blog entry involves a few manual steps:

  1. Write the blog. No difference there.
  2. Add a reference to the new post’s source file in an “entries.json” file. This allows the blog listing to find all the posts.
  3. Amend the webpack pre-renderer step to include the new blog page.
  4. Amend the sitemap.xml.
  5. Run a build (one simple bash script).

With a backend CMS, the content would be stored in a database, and the CMS would easily produce a sitemap and blog listing, though this also comes with greater maintenance and setup of the server. In my case, it just wasn’t worth the extra server overhead. Thinking about it, adding a couple lines to a couple files is a quicker process anyway than logging into an admin panel, adding a new blog entry, and adding the metadata, publish settings, etc.

I would happily use this approach for brochure sites and blogs of certainly much larger sizes, but not for anything more complex. I still think the rest of the web ecosystem needs to catch up a bit (especially search engines) before saying “this is it”. It’s certainly excellent for developers, but a project is about more than how it’s built.