Using Vue to enhance existing Multi page / server rendered / classic web app

axios.get(`/api/${payload.resource}?${payload.query}`, {params: {
			page: payload.page
		}})
		.then( (response) => {
			this.$set(this.data, resource, response.data)
			this.$set(this.loading, resource, false)
			this.$set(this.data[resource], 'page', payload.page)
        
		})
		.catch( (e) => {
			console.log(e)
			if (e.response.status == 401) {
				window.location.replace('/login')
			}
		})

This is my code for doing pagination. You’ll need to store the pagination token from your Java framework (Spring?).

This specifically covers ajax calls.

This is a non-SPA Vue app. Just don’t add a router and it’s non-SPA.

could you show some html markup please ? So i can see how this affects the markup rendered by the backend @rowanxmas

@rowanxmas i’m sorry to say it again but doing ajax calls isn’t the problem here, i know how to do ajax calls (all my jsfiddle links shows it btw)
wether axios or vue-resource or jQuery or even native fetch, i know how to use it, the problem here is how to replace html rendered by the server just on pagination change

this is not a non-SPA (the markdown page), this is exactly what an SPA is, wether there’s a front-end router or not, an SPA has only one page. I’m dealing with a multi-page / server rendered app for which my server has many urls :
/products?page=1
/products?page=2 …
and /products/1 …

here’s a more concret example of what i’m trying to acheive with a PHP version :
http://seo-vue-act-like-jquery.darkyluminex.fr/jquery
http://seo-vue-act-like-jquery.darkyluminex.fr/vanilla

no i would like to have the same behaviour but with vue :slight_smile:

<!DOCTYPE html>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">

<!-- favicon -->
<link rel="shortcut icon" href="{{ asset('/images/favicon.ico')}}">
<link rel="apple-touch-icon"  href="{{ asset('/images/apple-touch-icon.png') }}">
<link rel="apple-touch-icon" sizes="180x180"  href="{{ asset('/images/apple-touch-icon-retina.png') }}">

<!-- Styles -->
<!-- <link href="{{ asset('css/bootstrap-reboot.min.css') }}" rel="stylesheet">     -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">

<link href="{{ asset('css/element.css') }}" rel="stylesheet">    

</head>
<body>
	<div id="app">
	</div>

<!-- Scripts -->
<script src="{{ asset('js/manifest.js') }}{{ $major_version   }}"></script>
<script src="{{ asset('js/vendor.js')   }}{{ $major_version   }}"></script>
<script src="{{ mix('js/main.js')     }}{{ $current_version }}"></script>

</body>
</html>

This is the index.html that your Java server (grails/spring/etc.) should render. You’ll need a separate process that compiles Vue for you (e.g. vue-cli) and create the main/vendor/manifest js files and needed CSS.

thank you for showing me the markup, because now i really understand that we didn’t understand each other haha, this is not at all what my server is rendering, checkout this http://seo-vue-act-like-jquery.darkyluminex.fr/jquery, just look at the source code to see what my current server is rendering.

In your markup there’s no data so no SEO and that’s what i don’t want

Yeah, you can add whatever you need. I’m just showing the bare requirements for making Vue work.

thank you, please look at my link to understand in detail what i’m trying to acheive. Just to be clear again, i know the basics to setup a Vue project don’t worry :slight_smile:

https://jsfiddle.net/50wL7mdz/250755/

Swap the html content out once you fetch the new data. Kind of sucks that you have to code the template twice though.

https://jsfiddle.net/7270zft3/45/

1 Like

I don’t really have much time to explain but check out this demo I created https://jsfiddle.net/Akumzy/eywraw8t/3763/

in your example, if a google bot come’s, he’ll just see <h3 class="title is-4">{{name}}</h3> and that’s bad for SEO, that’s what i’m trying to solve, your exampel just shows an app with client rendered data, i want a server rendered data for the bot and client render for a browser @rowanxmas

this is exactly what i was expecting like answer, thanks a lot.
Now i can dig a bit more, the solution you gave me is the inital solution i found but the problem is the markup duplication, in the case of a bigger app (because my real app is a big e-commerce shop) it will be hard to maintain two templates each time. Do you have another idea ? @woodberry

@Akuma same as @rowanxmas, you two are just showing me regular front-end-only app, if a google bot see’s your content thats really bad SEO, and both of your examples are front-end data-driven, i’m looking much more for something like @woodberry said, and someone else on SO said https://stackoverflow.com/questions/49574918/using-vue-to-enhance-existing-multi-page-server-rendered-classic-web-app?answertab=votes#tab-top

@darkylmnx You could fetch the actual HTML from the API instead of just JSON, and then render that straight onto the page.

Pretty much what turbolinks does.

1 Like

any example with vue of turbo links ?

No, its a completely separate library - it doesn’t depend on vue.

I know, I meant do you have an example of both working together ?