От автора: в чем именно заключается проблема с vanilla Vue.js и SEO? Vue.js, как и многие другие фреймворки, такие как React, Angular и т. д., является фреймворком на стороне клиента, то есть веб-страница отображается с помощью JavaScript на стороне клиента. Эти приложения обычно называют одностраничными приложениями или SPA.
Когда SPA загружается в браузер, сервер отправляет только базовый HTML без какого-либо визуализированного содержимого. Он делает еще один запрос на получение пакета JavaScript. Затем JavaScript запускается в браузере для визуализации содержимого. Когда мы просматриваем исходный код страницы, мы видим что-то вроде следующего:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>My Blog</title> </head> <body> <div id="app"></div> <script src="/js/app.js"></script> </body> </html>
Видите в чем проблема? Когда поисковые роботы сканируют страницу, они получают только этот голый HTML без какого-либо контента. Нет данных для ботов, чтобы использовать их для индексации страницы.
Ну, SPA уже давно существуют, и Google говорит, что их сканеры теперь могут индексировать SPA. Но в этом аспекте довольно много неопределенности. Как долго сканеры находятся на странице? Что если размер пакета слишком велик? Что делать, если из-за какой-то ошибки страница не может правильно отображаться? Это повторение?
Давайте предположим, что он успешно смог отрисовать код на стороне клиента и правильно его проиндексировать. Значит ли это, что ваша страница теперь оптимизирована для поиска? Есть много критериев, которые определяют ранжирование страницы, и скорость загрузки страницы является одной из самых важных. SPA обычно медленнее при первой отрисовке контента по сравнению со старыми статическими страницами HTML / CSS, так как существуют затраты времени на выполнение вызова Ajax для извлечения пакета и его рендеринга.
Мы прошли долгий путь от этих статических HTML / CSS страниц, поэтому, очевидно, мы не сможем вернуться к ним снова. У этих методов были свои проблемы — каждый запрос должен идти на сервер для извлечения определенных общих данных, загрузки новых таблиц стилей для разных страниц каждый раз, когда пользователь перемещается, и т. д.
Есть ли решение, которое использует лучшие функции обоих методов, которое является SEO-оптимизированным и также очень быстро, как SPA? Ну, привет SSR!
Скриптинги на стороне сервера — это метод, используемый в веб-разработке, включающий использование скриптов на веб-сервере, которые создают полностью визуализированную страницу. Затем эта страница возвращается клиентскому приложению. SSR обеспечивает более быструю загрузку страниц, поскольку весь контент уже отображается на сервере. Давайте создадим одно такое приложение с помощью Nuxt.js.
Создание простого веб-приложения с помощью Nuxt.js
Выполните следующую команду, чтобы создать приложение Nuxt:
npx create-nuxt-app nuxt-blog-seo
Вы получаете следующие опции. Моя установка выглядит как на картинке ниже:
Если вы новичок в Nuxt, есть несколько вещей, которые Nuxt делает по-другому по сравнению с Vue:
Структура папок: Nuxt следует строгой структуре папок, которая не должна изменяться
Маршрутизация: Nuxt использует каталог pages для получения структуры маршрутизации (он выполняет автоматическое разбиение кода). Вы можете добавить внешний файл маршрутизации, но это не обязательно.
Ссылки маршрутизатора: вместо <router-link> Nuxt используется специальный тег <nuxt-link>.
Теперь перейдите в папку pages и измените файл index.vue следующим образом:
<template> <div class="container"> <h1>welcome to my page</h1> <div> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cum ex modi sapiente amet temporibus exercitationem qui nihil eius, nam sequi sint iste nostrum corrupti, similique in vel impedit inventore id! </div> </div> </template> <script> export default {} </script>
Запустите приложение с помощью команды npm run dev. Откройте веб-страницу и перейдите к просмотру исходного кода, и вуаля! Мы видим наш контент на странице исходного кода.
Давайте добавим еще одну страницу и ссылку на файл index.vue:
<!-- Article.vue --> <template> <div class="container"> <h1>A dummy article</h1> <div> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cum ex modi sapiente amet temporibus exercitationem qui nihil eius, nam sequi sint iste nostrum corrupti, similique in vel impedit inventore id! </div> </div> </template>
Теперь давайте добавим ссылку на эту страницу на главной странице:
<nuxt-link to=”/Article”> My Article </nuxt-link>
Сохраните код и снова запустите приложение, и вы сможете перейти на эту страницу. Вы заметили, что страница открывается мгновенно, точно так же, как будет работать SPA? После загрузки первой страницы Nuxt ведет себя как SPA. Просмотрите исходный код еще раз, и мы также можем увидеть полный исходный код страницы Article.vue! Это потому, что Nuxt создает статическую версию сайта (для статических ресурсов).
В файле Article.vue вместо использования фиктивных жестко закодированных данных на этот раз давайте извлечем их из Интернета. Для этого я буду использовать json placeholder и apiaxios. Мы добавили модуль Axios при создании приложения; к нему можно получить доступ в компонентах Vue, например, в виде плагина:
this.$axios .get('http://jsonplaceholder.typicode.com/posts/1') .then((res) => { return { fetchedData: res.data } })
Куда мы добавим этот код? Мы могли бы добавить его в хук created(), но created() работает только на стороне клиента, и это не то, что нам нужно.
Nuxt asyncData
asyncData указывает Nuxt визуализировать эту конкретную часть кода на сервере. Когда он работает на сервере, наш компонент Vue еще не инициализирован; таким образом, мы не можем использовать здесь this или какие-либо методы. Однако мы получаем объект Nuxt context, который содержит все эти данные.
<template> <div class="container"> <h1>{{ fetchedData.title }} test</h1> <div> {{ fetchedData.body }} </div> </div> </template> <script> export default { asyncData(context) { return context.$axios .get('http://jsonplaceholder.typicode.com/posts/1') .then((res) => { return { fetchedData: res.data } }) } } </script>
Откройте страницу еще раз и проверьте исходный код страницы. Мы видим, что сервер уже предоставил данные. Отлично!
Как Nuxt делает это?
Nuxt внутренне запускает Node-сервер в реальном времени. Таким образом, он может предварительно визуализировать страницы, даже не отправив их клиенту. Для размещения этого приложения нам нужен сервер, на котором можно запускать Node.js.
Означает ли это, что мы больше не можем размещать его на провайдерах статического хостинга, таких как Netlify? Ну, да — это жертва, которую мы должны принести. Но мы вернемся к этой проблеме позже.
Давайте добавим в наш маленький проект хранилище Vuex
Нет необходимости устанавливать Vuex, поскольку Nuxt автоматически делает это, когда видит содержимое в папке store. Я хочу отобразить имя пользователя на главной странице и на странице статьи. Нам нужно получить его с сервера. Вместо того, чтобы загружать его в обоих местах, давайте загрузим его один раз и сохраним во Vuex.
Создайте пользовательский модуль user.js во Vuex, создав новый файл внутри папки store:
export const state = () => ({ userName: 'default' }) export const mutations = { updateUserName(state, value) { state.userName = value } } export const actions = { getUserName(context) { return this.$axios .get('https://jsonplaceholder.typicode.com/users/1') .then((res) => { context.commit('updateUserName', res.data.name) }) } }
Здесь я получаю userName с сервера. Давайте отобразим его на обеих страницах:
<div>Name: {{ $store.state.user.userName }}</div>
Мы могли бы вызвать действие getUserName в методе asyncData, который выполняется на сервере, но Nuxt предоставляет специальный метод действия, называемый nuxtServerInit.
Метод nuxtServerInit
Этот метод автоматически вызывается Nuxt на сервере. Мы можем использовать его, чтобы заполнить хранилище на стороне сервера. Этот метод можно использовать только в основном модуле, поэтому давайте создадим в папке store файл index.js:
export const actions = { async nuxtServerInit(vuexContext) { await vuexContext.dispatch('user/getUserName', { root: true }) } }
Теперь действие getUserName будет вызвано автоматически, и userName будет заполнено на стороне сервера. Точно так же мы можем вызвать любое количество действий из разных модулей внутри nuxtServerInit.
Что насчет мета-тегов?
Мета-теги являются одним из наиболее важных факторов, влияющих на SEO. Nuxt использует внутренне vue-meta для генерации содержимого тега head, такого как тайтл страницы, метат-еги и т. д.
Так что здесь особенного? Мы также можем использовать vue-meta в vanilla Vue.js. В этом случае мета-теги Vue.js
заполняются одновременно с тем, когда JavaScript отображает страницу, поэтому боты могут или не могут получить мета-теги.
В тех случаях, когда мета-теги заполняются на основе последующего вызова Ajax, мы также можем видеть динамическое изменение тайтла страницы после получения ответа. Источник страницы не будет содержать мета-теги. Это очень плохо для SEO.
С другой стороны, Nuxt также предварительно отображает мета-теги! Даже если есть последующий Ajax-вызов, мы можем вызвать его в asyncData или в nuxtServerInit, которые выполняются на сервере. Поэтому во всех случаях боты при сканировании страницы получают обновленные мета-теги! Давайте рассмотрим это в действии.
Давайте добавим на страницу статьи тайтл страницы и мета-теги:
export default { asyncData(context) { return context.$axios .get('http://jsonplaceholder.typicode.com/posts/1') .then((res) => { return { fetchedData: res.data } }) }, head() { return { title: this.fetchedData.title, meta: [ { hid: 'description', name: 'description', content: this.fetchedData.body } ] } } }
После перезагрузки страницы просмотрите исходный код, и вы увидите, что они оба отображены.
Статический режим
Nuxt может генерировать статическую версию веб-сайта, которая оптимизирована для SEO и не требует от нас, чтобы получить все преимущества, запуска серверной части сервера Node в реальном времени. Мы можем просто разместить его на статических серверах, как и любое другое приложение Vue, и при этом иметь все преимущества SEO.
Чтобы выполнить сборку в статическом режиме, используйте следующую команду — она генерирует код для всех возможных маршрутов в dist каталоге:
npm run generate
Мы получили то, что нам было нужно!
Nuxt разработан с учетом SEO. С Nuxt мы можем взять под контроль многие факторы, которые влияют на SEO и ранжирование страниц. Nuxt заполняет пробелы и недостатки SPA и делает процесс создания SEO-оптимизированного приложения простым и приятным.
Автор: Preetish HS
Источник: https://blog.logrocket.com
Редакция: Команда webformyself.