Nuxt.js: Running nuxt generate on SPA mode should prerender meta tags

Created on 17 Aug 2019  路  5Comments  路  Source: nuxt/nuxt.js

What problem does this feature solve?

Allows Nuxt SPA mode to provide og:title and og:image to social media page share.

Currently there seem to be no way to show page title and image to facebook share. This was tested using the following tool.
https://developers.facebook.com/tools/debug/sharing/

Problem is that when using pre-fetched data through nuxt.config generate dynamic routing API call and payload, Nuxt only generates static files in Universal mode. Once switched to SPA mode, all static files are always empty and default meta specified in nuxt.config will show.

For my case I do not have the option to use SSR due to the host constraint.

What does the proposed changes look like?

'npm run build' or 'npm run generate' with SPA mode will generate static files that includes pre-fetched data. Potentially would be nice to generate the whole page, but minimum need the og:title and og:image meta tags for social media sharing.

This feature request is available on Nuxt community (#c9651)
feature-request

Most helpful comment

@pimlie If I override any meta tag in a page file (pages/example.vue) and I generate the whole project with nuxt generate the meta tags will be the same as the default what I defined in nuxt.config.js.

Reproduction steps:

  1. Generate a project with npx create nuxt-app and select SPA mode
  2. Update nuxt.config.js meta tags:
...
head: {
    title: process.env.npm_package_name || '',
    meta: [{ hid: 'og:title', name: 'og:title', content: 'Default' }],
  },
...
  1. Create a file under pages folder and override meta tags with the head function:
    (exampe: pages/blog.vue)
<template>
  <div class="container">blog</div>
</template>

<script>
export default {
  head () {
    return {
      meta: [{ hid: 'og:title', name: 'og:title', content: 'Overrided' }]
    }
  }
}
</script>

When I start the app with nuxt dev and I open the blog page I see this in devtools:

<meta data-n-head="1" data-hid="og:title" name="og:title" content="Overrided">

but when I use nuxt generate I see this:

<meta data-n-head="1" data-hid="og:title" name="og:title" content="Default">

It's reproducible with any meta tags, so I think it's a bug.
It's really painful problem when I want to use nuxt as a static SPA site.

All 5 comments

You can include a head section within your nuxt.config to set some defaults, but setting pre-rendered / page specific meta tags is against the SPA principle. If you need that then you need to use nuxt generate which does exactly what you are requesting ;)

@pimlie If I override any meta tag in a page file (pages/example.vue) and I generate the whole project with nuxt generate the meta tags will be the same as the default what I defined in nuxt.config.js.

Reproduction steps:

  1. Generate a project with npx create nuxt-app and select SPA mode
  2. Update nuxt.config.js meta tags:
...
head: {
    title: process.env.npm_package_name || '',
    meta: [{ hid: 'og:title', name: 'og:title', content: 'Default' }],
  },
...
  1. Create a file under pages folder and override meta tags with the head function:
    (exampe: pages/blog.vue)
<template>
  <div class="container">blog</div>
</template>

<script>
export default {
  head () {
    return {
      meta: [{ hid: 'og:title', name: 'og:title', content: 'Overrided' }]
    }
  }
}
</script>

When I start the app with nuxt dev and I open the blog page I see this in devtools:

<meta data-n-head="1" data-hid="og:title" name="og:title" content="Overrided">

but when I use nuxt generate I see this:

<meta data-n-head="1" data-hid="og:title" name="og:title" content="Default">

It's reproducible with any meta tags, so I think it's a bug.
It's really painful problem when I want to use nuxt as a static SPA site.

Hi @petergaal91,

Thanks for taking the time to provide a reproduction although I wasn't able to reproduce a bug there, and by bug I mean something that is not intended to be the actual behavior of a single page application (SPA).

Alright so here what's happening when you run your application in SPA mode, either with nuxt dev or nuxt generate:

  • you're requesting a page, let's say /blog ;
  • Nuxt will just provide the client a dummy HTML file with default content on it (the one from your nuxt.config.js) ;
  • then this HTML file will load JavaScript for the Vue application through its HTML script tags ;
  • among the Vue application there's the Vue Router, it'll take care of resolving current route on client side since we're running in SPA mode here ;
  • once the route is resolved it will mount the linked page Vue component ;
  • and resolve it's head property only then, on client side, applying its values to current HTML.

This happens so fast that if you're checking while running nuxt dev in the devtools you'll see the right meta already there because it got time to resolve your component head property but actually if you're looking at what nuxt dev really served you (right click > view page source) you'll see that you received the default meta set in your nuxt.config.js.
So yeah then if you generate your SPA application you'll end up with the same dummy HTML everywhere with default values from your nuxt.config.js in the generated dist folder but once you roll it into production you'll see it performing the same behavior as in nuxt dev, because that's how SPA are designed to work: everything is done on client side, no server work leverage at any time.
That's probably an issue for you because so far I don't think Facebook or any other social media are bothering with fetching and running JavaScript from pages you link on them in order to get you that sweet link card made from meta tags~ So I don't think there's any way to get different social media card previews depending on the link shared of an SPA application, it'll always be the default.

To conclude if you want your meta tags to be available right in the HTML for social media and such you'll have to run your application in universal mode and either use Nuxt as a server with server side rendering (SSR) or as a static site generator (SSG) depending on your needs.

Hope that was clear enough and that I'm not wrong on your issue, just wanted to dive a bit into it given how many thumbs up your message received~ Cheers!

Thanks the detailed explanation!

I forgot to drop a comment here, but I already switched to SSR (as you mentioned) a few months ago.

Hope that was clear enough and that I'm not wrong on your issue, just wanted to dive a bit into it given how many thumbs up your message received~ Cheers!

Thanks for clearing that up. I was facing a similar issue and with some investigation only slowly found out that using spa mode was the reason why my meta tags didn't update properly. Maybe there should be an improved documentation on the mode property (https://nuxtjs.org/api/configuration-mode/).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vadimsg picture vadimsg  路  3Comments

msudgh picture msudgh  路  3Comments

vadimsg picture vadimsg  路  3Comments

bimohxh picture bimohxh  路  3Comments

jaredreich picture jaredreich  路  3Comments