βοΈ Simplest implementation for Vue Server-side Rendering with any Backend

Search for a command to run...

No comments yet. Be the first to comment.
In this series/category, I would share with you guys all of my exp and best practices, to build the awesome products
Hi guys, Time flies, PHP is still being used and popular in the world π Getting started and working with PHP is totally awesome nowadays, we have plenty of tools to skyrocket your development experience (DX). Let's check them out π π IDEs PHPStor...
Hey guys, An update after I posted the βLaravel Excel: How to append rows to an existing Excel fileβ a while back. This post will give you another solution and probably a better way to export that fits every case. Problems Previously, when trying to ...

Hey guys, An easy topic for today! Make something a default (e.g., category, product, campaign, etc). Letβs go with the categories table for the examples. Letβs say we only want one category to be the default one. And find out which is the optimal wa...
Hey guys, Probably a chapter 2 of this https://sethphat.dev/why-is-wordpress-still-an-awesome-cms blog post, haha. Here was the story: Iβve been spending like 2 days figuring out which CMS I want to use for my new blog (for my new hobby lol) Letβs se...

Hey guys, Well damn, it has been a while since my last post lol, lazy & busy. But here I am, back to write useful tips for yβall π₯Ή Let us do some exporting tasks for today, using Laravel Excel to export XLSX (yeah CSV is so 2010 lol). But, append mo...

Hey guys, Recently, I just bought Herd PRO (a yearly subscription). Iβve been using the basic Herd since the first release. So, my latest work required interaction with S3 storage, there are several ways to achieve that in the local env: Use Cloud (...

Hey guys,
I recently discovered & successfully implemented server-side rendering using PHP + Laravel & Vue 3. Thought I would note them down here and share them with you guys, so I did π
With this simplest way, you will have the up-and-running Server-Side Rendering (SSR) in no time. You can even use any frontend framework as well πΉ
I'd call this the Minimalism Server-side Rendering (M-SSR) π
We all know the real benefits, critical ones are:
SEO improvements: yes, increasing your ranking on Search Engine (SE), helps SE to crawl your site better,...
Social Media Preview: when sharing our app's URLs to Facebook, Twitter,... they can crawl our content and show the preview better.
If you are working on internal projects that serve internal users and require authentication,... then you don't need SSR at all π

We only need to care about the first request. That's how SEs and Social Networks work, they access your page and then pick the rendered HTML for information.
If there are any redirects or transitions in the application after that, we don't need to care from the user's perspective.
Just keep your document.title updated and we're all good π
I'm adding the implementation for Laravel & Node x Express. It would be not so diff for other langs & frameworks π
We need to add the routes to have a 1:1 relationship with our Vue/React apps. For example, I have these routes under my Vue app:
Home /
Products List /products
Product Info /products/:slug
Contact us /contact-us
Then I'll add these routes in the backend service:
// web.php
Route::get('/', [HomeController::class, 'index']);
Route::get('/products', [ProductController::class, 'index']);
Route::get('/products/{slug}', [ProductController::class, 'show']);
Route::get('/contact-us', [ContactUsController::class, 'index']);
// index.ts
const routes = Router();
routes.get('/', viewHomePageHandler);
routes.get('/products', viewProductsListPageHandler);
routes.get('/products/:slug', viewSingleProductPageHandler);
routes.get('/contact-us', viewContactUsPageHandler);
Not a big deal, right? We can go either hard-coded or translated texts or retrieve simple info from the Database.
From our example above, static SEO content pages are Home, Products List, and Contact Us.
class HomeController {
public function index(): Response
{
$title = 'Home Page - Site Name';
$description = 'Welcome to Site Name, where you can skyrocket your app';
$socialPreviewImg = asset('assets/images/home-social-preview.jpg');
// to be continue...
}
}
export const viewProductsListPageHandler = (req, res) => {
const title = 'Products List - Site Name';
const description = 'Check out our products list and buy them';
const socialPreviewImg = 'https://image-here';
// to be continue...
};
This will be applied for the single product view page, we'll need to get the product details.
From Laravel, we can use the Model Route Binding feature to quickly access the model, it also handles 404 too (peace)
class ProductController {
public function view(Product $product): Response
{
$title = $product->name . ' - Your Site Name';
$description = $product->short_description;
$socialPreviewImg = $product->getSocialImage();
// to be continue
}
}
For Express app, I usually use a normal repository to get the data, feel free to use any kind of ORMs or anything that fits you most
export const viewSingleProductPageHandler = async (req, res) => {
const { slug } = req.params;
const product = await productRepo.getBySlug(slug);
if (!product) {
res.status(404);
return;
}
const title = product.name + ' - Site Name';
const description = product.short_description;
const socialPreviewImg = product.social_image;
// to be continue
}
Our view is now holding the index.html from Vite. Since it will be rendered from the backend side, we can render anything that we want:
meta tags
title
ld+json
...
// app.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>{{ $title }}</title>
<meta property="og:title" content="{{ $title }}" />
<meta property="og:description" content="{{ $description }}" />
<meta property="og:type" content="website" />
<meta property="og:image" content="{{ $socialPreviewImg }}" />
<!-- feel free to add more tags here -->
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" />
</head>
<body class="g-sidenav-show g-sidenav-pinned">
<div id="app"></div>
@vite('resources/js/app.ts')
<noscript>
<p>This site requires JavaScript to work.</p>
</noscript>
</body>
</html>
For node express: feel free to use any templating engine and follow the above. Some popular ones are HandleBars, underscore,...
From our controller methods, prepare and return the rendered view to the client π
class HomeController extends Controller
{
public function index(): Response
{
$title = 'Home Page - Site Name';
$description = 'Welcome to Site Name, where you can skyrocket your app';
$socialPreviewImg = asset('assets/images/home-social-preview.jpg');
// add more for your case
return response()->view('app', [
'title' => $title,
'description' => $description,
'socialPreviewImg' => $socialPreviewImg,
]);
}
}
Node app, follow the same approach like above π
No further action or any package is required, minimalism isn't it? π
Simply run your backend and test the result π
Congrats, you are now using M-SSR for your applications.
Let's summarize the PROs & CONs π₯Ή
Simplest solution π
Super easy to implement πΉ
No extra package is needed, use what you already have π
Hot-reloading works fine, no need to worry π₯
Only the first request will have the correct tags, if users go to another page, they still have the same tags
document.title and that's all πNeed a simple backend service to serve the first request (BE + FE in the same repo)
Check out DevToolz https://tools.sethphat.dev/ π
The DevToolz Repository: https://github.com/sethsandaru/devtoolz
Hope this will help you to skyrocket the SEO of your websites, blogs, or whatever you are developing for your end-users πΉ
Happy coding π!