How Nuxt.js helps you with SEO
Before we get into the main point of this article, let’s first quickly find out what Nuxtjs is and how it can help the application respond to SEO purposes.
Single Page Applications aren’t set up for SEO
Usually with Vue.js, you will create a single page application (SPA). It’s an application generated entirely by JavaScript and in a blank index.html
file. Content is rendered into index.html
after JavaScript is loaded and JavaScript also takes care of switching between routers.
SPAs are great for creating user UI flexibly, but when it comes to SEO, SPAs aren’t ideal because they don’t have initial content
. That makes it difficult for Google and other crawlers (including social media crawlers like Facebook) to crawl your site and render it correctly in the link. search results.
Nuxt.js makes it simple to create a universal application
A universal application is to pre-load the application on the web server and send the rendered HTML as a response to the browser so that each route in your app improves SEO, for faster loading, among many other benefits.
For a universal application, the content on the page will have some tags like <title>
and <meta>
tag in <head>
and <h1>
tag in <body>
before any JavaScript is loaded. Those tags help crawlers identify what is on the page.
How Nuxt.js handles the head for all your pages
Nuxtjs uses a library called vue-meta
to handle the <head>
tag on every page. Page is just Nuxtjs’ term for a route and each page is inside a pages folder. Nuxtjs provides you with three ways to set up the <head>
element in your application pages. Let’s see what they are below.
1) Setting up default meta tags for all pages
It’s not uncommon for different pages in the application to share some of the same meta tags. Nuxtjs allows you to set default values for each of your pages by setting the head attribute in the nuxt.config.js
file.
1 2 3 4 5 6 7 8 9 10 11 | module <span class="token punctuation">.</span> exports <span class="token operator">=</span> <span class="token punctuation">{</span> head <span class="token operator">:</span> <span class="token punctuation">{</span> titleTemplate <span class="token operator">:</span> <span class="token string">'%s - Nuxt.js'</span> <span class="token punctuation">,</span> meta <span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token comment">// Each object in this array is its own meta tag</span> <span class="token punctuation">{</span> charset <span class="token operator">:</span> <span class="token string">'utf-8'</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> name <span class="token operator">:</span> <span class="token string">'viewport'</span> <span class="token punctuation">,</span> content <span class="token operator">:</span> <span class="token string">'width=device-width, initial scale=1'</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> hid <span class="token operator">:</span> <span class="token string">'description'</span> <span class="token punctuation">,</span> name <span class="token operator">:</span> <span class="token string">'description'</span> <span class="token punctuation">,</span> content <span class="token operator">:</span> <span class="token string">'Meta description'</span> <span class="token punctuation">}</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> |
You can click here to see all the properties that you can define within the head
attribute. Note: Nuxt.js uses head
for the name of the property. vue-meta
uses metaInfo
. It is the same property.
2) Setting up meta tags for your pages individually
Inside each of your Nuxtjs pages, you can define the head
method. You can also manually customize the head tags for an individual page and Nuxtjs will override the settings you set as default in the nuxt.config.js
file.
Below is an example of the About.vue
file with its own meta tags in the head
method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <template> <h1>About Page</h1> </template> <script> export default { head () { return { title: 'About Us - Nuxt.js', meta: [ { hid: 'description', name: 'description', content: 'About our company Nuxt.js ' } ] } } } </script> |
3) Setting up meta tags for your dynamic pages
You can further customize your meta tags with dynamic pages – pages including a route can be rendered differently. A page user profile could be an example.
Dynamic routes are defined by adding the prefix .vue
component or directory in the pages folder with an underscore.
1 2 3 4 | pages/ --| users/ -----| _username.vue |
This will generate your Vue.js
route code like so:
1 2 3 4 5 6 7 8 | router <span class="token operator">:</span> <span class="token punctuation">{</span> routes <span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> name <span class="token operator">:</span> <span class="token string">'users-id'</span> <span class="token punctuation">,</span> path <span class="token operator">:</span> <span class="token string">'/users/:username?'</span> <span class="token punctuation">,</span> component <span class="token operator">:</span> <span class="token string">'pages/users/_username.vue'</span> <span class="token punctuation">}</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span> |
And inside the head
method, you can access your component data with this
. You can use the data that you have access to within this
section to customize the way your meta tags are displayed with the data in your component.
Here is an example of how meta tags for the page user profile can be rendered:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <script> head () { let user = this.user; return { title: `${user.fullName} @(${user.userName}) - Nuxt.js`, meta: [{ hid: `iOSUrl`, property: 'al:ios:url', content: `myapp://user?screen_name=${user.userName}` }, { hid: `description`, name: 'description', content: `${user.fullName}'s public profile at Nuxt.js` }] } } </script> |
What is hid and how does it help SEO?
You can notice the hid
attribute in the meta tag examples above. It’s an attribute that is being used to help minimize the default vue-meta
behavior.
By default, when using vue-meta
, it will generate duplicate tags instead of replacing the original tag. But Google can penalize you for having duplicate tags when it crawls your site, so it’s best to always have a unique hidden attribute on each of your meta tags to uniquely identify them. . Having the hidden
property signals the vue-meta
to replace the tag instead of copying it.
You can click here to learn more about duplicate meta tags and how hid
can help you avoid this problem.
Handling redirects with Nuxt.js
According to HubSpot , a 301 redirect is a permanent redirect from one URL to another. A 301 redirect takes website and search engine visitors to a URL other than the one they originally entered into their browser or picked up from a search engine results page.
301 redirects are commonly used when your site structure changes and you still want to maintain the original link’s ranking power.
Nuxtjs help you in this case by setting an attribute you serverMiddleware
inside files nuxt.config.js
of you. The serverMiddleware
property lets you set-up middleware that will run when the page is rendered on the server side.
Below is an example of using this property to set-up a 301 redirect handler for your application.
1 2 3 4 5 6 | module.exports = { serverMiddleware: [ '~/servermiddleware/seo.js' ] }; |
You can define the routes that need to be redirected inside a file named /301.json
and import it into the seo.js
middleware.
1 2 3 4 5 6 | [ { "from": "/old", "to": "/new" }, { "from": "/veryold", "to": "/verynew" }, { "from": "/too-old", "to": "/new" } ] |
You can then run the file through the routes you defined in 301.json
and it returns a 301 response for each route, along with the appropriate HTTP headers.
1 2 3 4 5 6 7 8 9 10 11 12 13 | const redirects = require('../301.json'); module.exports = function (req, res, next) { const redirect = redirects.find(r => r.from === req.url); if (redirect) { console.log(`redirect: ${redirect.from} => ${redirect.to}`); res.writeHead(301, { Location: redirect.to }); res.end(); } else { next(); } } |
You can click here to learn more about the Nuxt.js middleware and how it can help you with more than just a redirect.
SEO effects when rendering your app in spa mode
There is more than one built mode in Nuxtjs applications. You can choose to show your app in universal or spa form.
The effect of managing all tags in <head>
if you choose to display your app in spa mode?
Since server-side rendering isn’t happening, you won’t get any benefit from having the original content on your page. vue-meta still does the job of handling <head>
, but if you are rendering your app as a single page application, initially there will be no content on the page as all the tags will be create after JavaScript has finished loading. The only effects are purely the user interface. For example, title tag updates when the user has changed the view.
References
https://medium.com/vue-mastery/best-practices-for-nuxt-js-seo-32399c49b2e5