spatie / laravel-server-side-rendering

Server side rendering JavaScript in your Laravel application
https://sebastiandedeyne.com/posts/2018/server-side-rendering-javascript-from-php
MIT License
662 stars 63 forks source link

How do I configure vue router? #67

Closed wovosoft closed 4 years ago

wovosoft commented 4 years ago

This is package is really helpful. I have managed to render vue components successfully. But Now I am facing problem integrating vue-router . It would be great if anyone can provide me an example. Thanks

jcsoriano commented 4 years ago

You will want to have a fallback route that shows the blade file with the server-side-rendered vue-router app. This way, any route that isn't handled by the server is passed on to be handled by vue-router

wovosoft commented 4 years ago

Thanks @jcsoriano I have already figured it.

sajadabs commented 3 months ago

Hi when you add Renderer $renderer to entry of controller function this variable have route path in it. and when use it like this : $html = $renderer->entry(storage_path('app/ssr/entry-server.js'))->render(); In the rendering process, a variable named context is created and placed in the js file that is created temporarily in storage ssr folder . define router index.js like this

import qs from 'qs';

import { createRouter as _createRouter, createWebHistory, createMemoryHistory } from 'vue-router';

export function createRouter() {
    return _createRouter({
        history: typeof window === 'undefined' ? createMemoryHistory() : createWebHistory(),
        routes: [
            {
                path: '/blog/',
                name: 'BlogView',
                component: () => import("@/view/BlogView.vue"),
            },
            {
                path: '/blog/:slug?',
                name: 'PostView',
                component: () => import("@/view/PostView.vue"),
            }
        ],
        parseQuery(query) {
            return qs.parse(query);
        },
        stringifyQuery(query) {
            return qs.stringify(query);
        }
    });
}

and in entry-server.js push router to requested page using context created in render process like this :

import { createApp } from './main'
import { renderToString } from 'vue/server-renderer'

export async function render() {

    const { app, router } = createApp()

    if (typeof context !== 'undefined') {
        await router.push(context ? context.url : '/')
        await router.isReady()
    }

    const ctx = {}
    const html = await renderToString(app, ctx);

    if (typeof dispatch !== 'undefined') {
        dispatch(html)
    }
}

render();

also you should add routes in laravel routes like this :

Route::get('/blog', [PostController::class, 'index']);
Route::get('/blog/{title}', [PostController::class, 'show']);

and now when app loaded you can see vue router is working :) I hope this solution is helpful for you who read this. ;)