Vue Spa show <noscript> tag content as description text in search engine. ex.Google search - vue.js

I have a landing page build using Vue 2 with vue router and vue pwa.
When public to production, everything run okay but when i search my web in Google, results show only title page, content in noscript tag as description and when view cached version of my page Google show totally empty page.
But my web on production still run normal, full function and i definitely don't disable Js in browser. I also tried use Google Search Console to request re-index my page but nothing change.

Disable prefetch and preload in vue.config.js resolved my problem.
chainWebpack: config => {
config.plugins.delete('preload')
config.plugins.delete('prefetch')
},

Everything turned on in the server? Just had that happen today anyway what code you using to add the title and description. Looks like something may not be executing when the page loads.

Related

VueJS real SEO friendly 404 page for search engines like Google / MSN

I am not VueJS programmer, but I work with in a company where we developing a VueJS website.
The website have articles. The URL is something like this:
http://example.com/here_is_news_from_sofia.htm
However if you type:
http://example.com/here_is_news_from_blabla.htm
You should go to 404 page.
I inspected several websites and stackoverflow questions, they explain how you should do catch-all router etc, so finally you get a page with "404 Not Found" text on it.
However, in ALL cases, the HTTP code send to the client is not 404, but 200.
With my team, I elaborated this:
When you go to any article, you get something like this:
<html>
<body>
<div id="app">
<app />
</div>
<script src="/js/client.js"></script>
</body>
</html>
Of course, if you click on a link, this page remains and everything is loaded via JS dynamically.
Then lets suppose article is not found.
VueJS will be able to show "404 Not Found" as text, but because HTTP headers are already send (HTML page is already loaded), it will not be able to send 404 code to the client.
For the same reason, VueJS can not send 301 code redirect to the client.
VueJS can incorrectly change the URL in the browser to "http://example.com/404.htm" - this is NOT a correct solution for search engines, since this is purely client-side (in-browser) "trick".
The other think it can do is to execute fancy redirect, as shown here Vue-router redirect on page not found (404) :
Vue.component("page-not-found", {
template: "",
created: function() {
// Redirect outside the app using plain old javascript
window.location.href = "/404.htm";
}
}
This will make the browser to reload the /404.htm page from the server and if the server (Apache / Nginx) is configured correctly, it will send "correct" 404 code to the client.
However I don't think Google and MSN will recognize that http://example.com/here_is_news_from_blabla.htm is a 404 page.
Am I missing anything?
Is there another way VueJS might handle this situation?
How VueJS websites gets indexed from search engines like Google and MSN?
Off topic bonus question - can VueJS generate visible HTML code that contains the article?
If that's a single page application, you can set up dynamic route matching with parameters with vue-router. And dynamically update your meta tags with javascript. I am using quasar vue framework, which handles all of this SEO feature.
I added slug data to the article saved in the database and use it as a route parameter.
https://quasar.dev/vue-composables/use-meta
https://router.vuejs.org/guide/essentials/dynamic-matching.html
You can use quasar vue framework, develop vue app in SSR mode and deploy it to the server.
https://quasar.dev/quasar-cli-vite/developing-ssr/handling-404-and-500-errors

How would I make Vue Router work with GitHub Pages?

I just deployed my Vue app to my website using GitHub Pages.
The website is successfully hosted at https://astroorbis.com.
Here's the problem; When you click the "links" button at the top of the page, it successfully nagivates you to https://astroorbis.com/links, but when you try visiting the URL itself (typing in https://astroorbis.com/links) into your browser, it returns a 404.
There are other links that have the same error, such as /discord, /github, etc.
I tried the solution at Vue Router, GitHub Pages, and Custom Domain Not Working With Routed Links, but it failed as well.
What would be the solution for this?
As stated in this section of the HTML5 mode
Here comes a problem, though: Since our app is a single page client side app, without a proper server configuration, the users will get a 404 error if they access https://example.com/user/id directly in their browser. Now that's ugly.
Not to worry: To fix the issue, all you need to do is add a simple catch-all fallback route to your server. If the URL doesn't match any static assets, it should serve the same index.html page that your app lives in. Beautiful, again!
So, the solution would be to use something like that
const routes = [
// will match everything and put it under `$route.params.pathMatch`
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
]
On Netlify, you also need to add the following for it to work
/public/_redirects
/* /index.html 200
So I'm not sure about Github Pages but you should have something similar there, some way of catching all routes and sending them to the index.html of your initial SPA page load.
Otherwise maybe just give a try to Netlify with the _redirects configuration.
Maybe this article could help regarding Github pages.
The hack in your given link seems to be the only viable solution but it's still bad for SEO so yeah, depends if you want any (I guess so).
In that case, you could try Nuxt.js, Gridsome or Vitesse if you want to have some statically generated pages (best approach regarding SEO).

Why doesn't my nuxt static site serve the static html files found in the Dist folder?

I've created a blog with Nuxt that has dynamic routes for each of my articles (articles/_slug.vue). Inside the _slug.vue file I grab markup content from a strapi CMS using asyncData.
aricles/_slug.vue
After running nuxt generate followed by nuxt start and navigating to an article page in my browser, when I open the page source I find that there are numerous Js files being imported /_nuxt/{randomNumbers}.js and a single div with an id __nuxt , most likely resembling an SPA format.
page source of an article
This does not occur with my index.vue page as when I view the page source for index.vue all my content is in the HTML.
Its important that the google crawler is able to index the content on my article pages, so the page source not containing the blog content is not ideal.
What I don't understand is that when I open the dist folder generated by nuxt I find all my articles in subfolders containing HTML files hard coded with my blog content. So I am wondering why isn't nuxt serving these HTML files , and is there a way to do so ?
distFolder
As far as I know all pages and components go in one component called Nuxt and I think the "__nuxt" element is that. By the way using asyncData and 'nuxt generate' won't make your app server-side dynamic because 'nuxt generate' generates a static site and while using 'nuxt generate' all asyncData hooks will be called once. For the hard coded blog posts I think you should disable Nuxt Crawler in your nuxt.config.js.
Nuxt Docs: The Generate Property #Crawler
export default {
generate: {
crawler: false
}
}
It seems as though after hosting the project on Vercel the static behavior works accordingly. When testing the website locally (nuxt start) the content isn't pre loaded into the page source it continues to act as a SPA on dynamic routes. However after deploying to Vercel the blog content can be found in page source.

Error 404 on a page that exists and that works fine through internal link

I created a website with several pages on Vue.js.
Everything is working fine locally, but when I deploy to Heroku, all pages are only working when I click on an internal link in my menu that redirects to the corresponding page (using router push).
When I try to access directly /any-page from the browser I get a 404 with a message saying "Cannot GET /any-page" whereas the same page is displayed correctly via a click on a link.
As I mentioned when I locally serve my app I don't have this problem.
I really can't see where this can come from, thanks in advance for your help.
There's a deployment guide specifically for Heroku in the official Vue CLI documentation.
You'll quickly notice the relevant information:
static.json
{
"root": "dist",
"clean_urls": true,
"routes": {
"/**": "index.html"
}
}
For SPA's (Single Page Applications), you'll want to point every route to the index. Vue router will take care of navigating to the proper page.
Heroku is serving the contents of your Vue build folder. Since Vue builds the app as a single index.html file, only the main route works.
Vue doesn't actually navigate to the route, it rather rewrites the the browser url using the history API and handles the loading of the new route.
You could use one of these options:
OPTION 1
You could use mode: "hash" to fix routes when reloading the page. However this will add a # before every route.
const router = new VueRouter({
mode: "hash",
routes: [...]
})
OPTION 2
Write an Node.JS (eg Express) app that routes every request to your index.html file. This is called a middleware
Reference: https://router.vuejs.org/guide/essentials/history-mode.html#example-server-configurations

Custom nuxt 500 error page with preloaded state

Environment: Nuxt.js (Vue/Vuex/Node framework with SSR).
If user encounters an Internal Server Error, I want to use a custom Vue template, similar to the one I'm already using for 404 errors.
By looking at Nuxt source, it looks like the only way is to add a custom 500 page is to override the default .nuxt/views/error.html with my own custom error page.
I don't want just a static HTML page that the user must click out of to re-enter the app, though. I want it to still load the Nuxt app with some preloaded '500 error' state.
In Nuxt docs I don't see how to accomplish this. Any advice?
Things I have tried already:
Redirecting from error.html (doesn't work because of double redirect)
Iframe (works, but don't want to do it this way)