0

I am learning Vue and got stuck trying setup it as full front-end with Laravel, on my scenario I already have made an personal blog for test using Laravel with Blade engine and some components of Vue and seems work fine.

I am trying get on next level, removing Blade and letting Laravel as API backend and setup Vue as full front end with SSR, the basic setup works, I mean I can call Vue, render it using SSR with node or PHPv8, the problem I am having is on route systems, thinking as blade way I can't archive same result, on blade I use an default layout as master and import it for every post, page, blog, etc...

Example:

resources/views/layouts/master.blade

<!DOCTYPE html>
<html dir="ltr" lang="{{ app()->getLocale() }}">

    <head>
        @include('partials._head')
    </head>

    @if(View::hasSection('body')) {{-- Load Custom Body --}}
        <body @section('body')>
    @else
        <body>
    @endif

        @yield('content')

        @include ('partials._javascripts')

        @section('scripts')
    </body>

</html>

So I call a dynamic head per page / post, a dynamic content, an basic javascripts (bootstrap, vue, fontawesome, etc...) and custom 'scripts' per page / posts.

Using the librarie:

https://github.com/spatie/laravel-server-side-rendering

I can get SSR working with node or PHPv8, but the vue-route never call the desired page, my setup is:

resources/assets/js/app.js

import Vue from 'vue';
import App from './layouts/App';
import axios from 'axios';
import store from './store';
import router from './router';
import navbar from './components/navbar';
import posts from './components/posts';
import sidebar from './components/sidebar';
import footer from './components/footer';
import BlogIndex from './views/blog/BlogIndex';



export default new Vue({
    store,
    router,
    navbar,
    posts,
    sidebar,
    footer,
    BlogIndex,
    render: h => h(App),
});

resources/assets/js/entry-client.js

import app from './app';

app.$mount('#app');

resources/assets/js/entry-server.js

import app from './app';
import renderVueComponentToString from 'vue-server-renderer/basic';

app.$router.push(context.url);

renderVueComponentToString(app, (err, html) => {
    if (err) {
        throw new Error(err);
    }
    dispatch(html);
});

resources/assets/js/router.js

// router.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from './components/Home';
import BlogIndex from './views/blog/BlogIndex';

Vue.use(VueRouter);

const routes = [
    { path: '/', name: 'home', component: Home },
    { path: '/blog', name: 'blog', component: BlogIndex },
];

export default new VueRouter({
    mode: 'history',
    routes,
});

resources/assets/js/store.js

import Vue from 'vue';
import uniq from 'lodash/uniq';
import Vuex, { Store } from 'vuex';

Vue.use(Vuex);

export default new Store({
    state: {
    },

    getters: {
    },

    mutations: {
    },
});

resources/assets/js/views/blog/BlogIndex.vue

<template>
    <div class="container">
        <navbar></navbar>
        <posts></posts>
        <sidebar></sidebar>
        <footer></footer>
    </div>
</template>



<script>

    export default {
        name: "BlogIndex",
        components: {
        }
    }
</script>

<style scoped>

</style>

app/Http/Controllers/VueSSRController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Routing\Route;

class VueSSRController extends Controller
{

    public function __invoke()
    {
        return view('layouts.vue');
    }

}

resources/views/layouts/vue.blade.php

<!DOCTYPE html>
<html dir="ltr" lang="{{ app()->getLocale() }}">

    <head>
        @section('extrajavascripts'){{ asset('js/scripts.min.js') }}@endsection
        @include('partials._head')
    </head>

    @if(View::hasSection('body')) {{-- Load Custom Body --}}
    <body @section('body')>
    @else
    <body>
    @endif

        {{-- Begin of Vue SSR --}}
        {!! ssr('resources/assets/js/server_bundle.min.js')
            // Share the packages with the server script through context
            //->context('packages', $packages)
            // If ssr fails, we need a container to render the app client-side
            ->fallback('<div id="app"></div>')
            ->render() !!}
        {{-- End of Vue SSR --}}

        @include ('partials._javascripts')

        @section('scripts')
        @show

    </body>

</html>

/resources/assets/js/layouts/App.vue

<template>
    <div id ="app">
        {{ message }}
    </div>
</template>

<script>
    export default {
        name: "App",
        data() {
            return {
                message: 'SSR working.'
            }
        }
    }
</script>

<style scoped>

</style>

So SSR works fine, the problem is the resources/assets/js/router.js is not loading the resources/assets/js/views/blog/BlogIndex.vue, the url/blog works, but the component rendered is always the /resources/assets/js/layouts/App.vue.

Someone would point what I am missing setup please?

Thanks in advice!!!

2
  • I was also set up this on my local system. I am curious to know what did you write inside the web.php i.e routes. Commented Aug 21, 2021 at 6:00
  • @SachinKumar Unfortunately I had to abandon this setup as it was time consuming, in the end I ended up creating a subdomain for the laravel example api.website.com and working directly with Nuxt in the main domain website.com. Commented Dec 7, 2021 at 6:52

1 Answer 1

1

You should place <router-view></router-view> where you want the router to load. I think in your case its below {{message}} in App.vue

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much!!!! You right, that started render the correct views. That message is only for debug, looking for the tag data-server-rendered="true" on source.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.