Как сделать ваше приложение Angular 4 SEO дружественным

  1. Начало работы с SEO-приложением для Angular 4
  2. Настройка нашего тестового приложения Angular 4
  3. Делаем приложение Angular 4 SEO дружественным
  4. Тестирование нашего дружественного к SEO приложения Angular 4
  5. Заключение

Приложения Angular 4 загружают первый чистый HTML-контент перед извлечением HTML-контента для страницы, загружаемой с использованием XMLHttpRequest. Одностраничные приложения потрясающие! Они загружаются быстро и дают вам большой контроль над тем, как вы хотите, чтобы ваше приложение работало. Они анализируются браузером, и, таким образом, у вас есть контроль над элементами DOM и всем этим.

Тем не менее, SPA не являются SEO дружественными, потому что им нужно динамически изменять метатеги и контент с помощью JavaScript, и это изменение обычно не воспринимается ботом поисковой системы. Поскольку некоторые поисковые роботы не могут анализировать JavaScript при сканировании веб-сайта, они будут видеть только первый голый контент каждый раз.

Хотя Гугл говорит их боты теперь способны рендерить JavaScript, это все еще неясная область, и ошибка в осторожности будет лучшим способом решения этой проблемы. Также есть другие поисковые системы, которые не обрабатывают JavaScript. Эта статья расскажет, как сделать ваше приложение для Angular 4 более удобным для SEO и таким образом облегчить его использование роботами поисковых систем.

⚠️ Это не учебник по Angular 4, и мы не будем рассказывать о специфике платформы Angular 4. Мы просто покажем вам, как использовать рендеринг на стороне сервера для обслуживания полностью сгенерированной HTML-страницы.

Начало работы с SEO-приложением для Angular 4

Прежде чем приступить к обучению, давайте создадим простое приложение, которое мы будем использовать для тестирования нашей реализации. Приложение будет страница, которая перечисляет кучу тем на главной странице. Мы не будем подключаться к какому-либо источнику данных, но вместо этого мы будем жестко кодировать данные в компоненте.

Настройка нашего тестового приложения Angular 4

Для настройки нашего приложения Angular мы будем использовать нг-кли , и мы будем называть приложение Блогист .

Создание нового приложения с использованием ng-cli
Для настройки мы будем использовать команду ng new для создания приложения Angular 4.

$ ng new Blogist

⚠️ Примечание. Для правильной работы этого приложения вам потребуется последняя версия Angular CLI. Последняя версия 1.3.x на момент написания этой статьи.

Далее мы просто создадим компонент, в который затем сможем добавить логику нашего кода. Для этого мы будем использовать команду компонента ng g:

Компонент $ ng g ./blog/posts

Добавление фиктивных данных в наш PostComponent
Для краткости мы не будем подключаться к внешнему API. Вместо этого мы просто будем создавать некоторые фиктивные данные и использовать эти данные в нашем приложении.

Откройте файл ./src/app/blog/posts.component.ts, и мы добавим некоторую логику в код, чтобы убедиться, что он работает так, как нам нужно. Во-первых, давайте жестко закодируем некоторые данные в файл. Добавьте новый метод postsData к компоненту.

private postsData () {return [{"title": "Создание Angular.js в реальном времени с мраморными Websockets", "pubDate": "2017-08-23 14:41:52", "link": "https: // blog.pusher.com/making-angular-js-realtime-with-pusher/#comment-10372 "," guid ":" http://blog.pusher.com/?p=682#comment-10372 "," author ":" marble "," thumbnail ":" "," description ":" всегда большой поклонник ссылок на блоггеры, которые мне нравятся, но я не получаю много удовольствия от ссылок "," content ":" <p> всегда большой поклонник ссылок на блоггеры, которые мне нравятся, но я не получаю много удовольствия от ссылок из </ p> "," enclosure ": []," Categories ": []}, {" title ":" Создание Angular .js в режиме реального времени с Websockets без бретелек ремешком на "," pubDate ":" 2017-08-23 05:05:08 "," link ":" https://blog.pusher.com/making-angular-js-realtime -with-pusher / # comment-10371 "," guid ":" http://blog.pusher.com/?p=682#comment-10371 "," author ":" ремень без бретелек "," thumbnail ": "", "description": "очень несколько интернет-сайтов, которые будут подробно описаны ниже, с нашей точки зрения w, несомненно, стоит проверить "," content ":" <p> пара веб-сайтов, которые будут подробно описаны ниже, с нашей точки зрения, несомненно, стоит проверить </ p> "," enclosure ": [], "Categories": []}, {"title": "Создание Angular.js в реальном времени с помощью Websockets с помощью ограничений связывания", "pubDate": "2017-08-22 17:09:17", "link": "https://blog.pusher.com/making-angular-js-realtime-with-pusher/#comment-10370", "guid": "http://blog.pusher.com/?p=682#comment -10370 "," author ":" ограничения рабства "," thumbnail ":" "," description ":" очень немногие веб-сайты, которые оказываются в глубине ниже, с нашей точки зрения, несомненно, заслуживают того, чтобы их проверить " , "content": "<p> очень немногие веб-сайты, которые находятся ниже, с нашей точки зрения, несомненно, стоит проверить </ p>", "enclosure": [], "Categories": []}]; }

Чтобы использовать наши фиктивные данные, созданные выше, замените метод конструктора класса PostsComponent на код ниже:

публичные посты; constructor () {this.posts = this.postsData (); }

В приведенном выше коде мы просто присвоили свойству posts возвращаемое значение postsData, которое является нашим имитированным ответом на вызов API.

Создание представления для нашего PostsComponent
Теперь, когда у нас есть данные о ложных публикациях. Мы создадим представление, которое будет отображать все сообщения из наших фиктивных данных.

Откройте ваше представление ./app/blog/posts.component.html и введите код ниже:

<div class = "jumbotron"> <h1> Blogist </ h1> <p> Это лучший ресурс для лучших публикаций по веб-разработке. </ p> </ div> <div class = "row"> <div class = "col-xs-12 col-md-12"> <ul class = "list-group"> <li class = "list-group-item" * ngFor = "публиковать сообщения"> <h4> {{ post.title}} </ h4> </ li> </ ul> </ div> </ div>

Код выше просто берет данные постов и проходит через них; каждый раз отображается заголовок поста.

Затем откройте файл index.html и в разделе <head> замените содержимое следующим кодом. Он в основном использует Bootstrap и добавляет фиктивную панель навигации:

<! doctype html> <html lang = "en"> <head> <meta charset = "utf-8"> <title> Блогист </ title> <base href = "/"> <meta name = «viewport» content = "width = device-width, initial-scale = 1"> <link rel = "icon" type = "image / x-icon" href = "favicon.ico"> <link rel = "stylesheet" href = "https : //cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css "> </ head> <body> <nav class =" navbar navbar-default "> <div class = "container-liquid"> <div class = "navbar-header"> <a class="navbar-brand" href="#"> Блогист </a> </ div> <ul class = "nav navbar- nav "> <li class =" active "> <a href="#"> Сообщения </a> </ li> <li> <a href="#"> Веб-разработка </a> </ li> < li> <a href="#"> Графический дизайн </a> </ li> </ ul> </ div> </ nav> <div class = "container"> <app-root> Загрузка ... < / app-root> </ div> </ body> </ html>

Регистрация PostsComponent с нашим модулем приложения
Следующее, что мы сделаем, это зарегистрируем PostsComponent с нашим модулем приложения.

💡 Обратите внимание, что использование команды ** ng g component ** автоматически зарегистрирует компонент в модуле приложения. Таким образом, вам не нужно делать это снова. Если это было сделано для вас, вы можете пропустить этот шаг.

Если он не был зарегистрирован автоматически, откройте файл ./src/app/app.module.ts и импортируйте PostsComponent:

import {PostsComponent} из './blog/posts.component';

Затем в массиве объявлений NgModule добавьте PostsComponent в список:

@NgModule ({объявлений: [... PostsComponent,], ...})

Отображение вашего углового приложения
После регистрации нашего компонента Posts мы добавим его в наш файл ./src/app/app.component.html, чтобы отобразить компонент posts. Откройте файл ./src/app/app.component.html и добавьте в него следующий код:

<приложение-сообщения> </ приложение-сообщения>

Это все!

Теперь, когда вы запустите ng serve и перейдете по URL, предоставленному вам на вашем терминале. Вы должны увидеть страницу с нашими сообщениями:

Отлично, это именно то, что мы ожидали. Однако при просмотре источника URL-адреса вы заметите, что отсутствует все тело страницы, и видна только часть <app-root> loading… </ app-root>.

Это из-за того, как работает Angular. Сначала будет загружен родительский шаблон, а затем сам.

Затем он запустит процесс манипулирования DOM, который вставит содержимое каждой последующей страницы в тег <app-root>.

Следовательно, когда робот поисковой системы запрашивает эту страницу, он получает HTML <app-root> Загрузка… </ app-root> выше, и содержимое страницы, которая должна была способствовать SEO, теперь неизвестно движку.

Делаем приложение Angular 4 SEO дружественным

Теперь, когда мы создали пример приложения, мы сразу видим, что оно не оптимизировано для SEO. Таким образом, мы будем использовать сервер универсальной платформы Angular для предварительной рендеринга шаблонов на стороне сервера и обслуживания при загрузке страницы.

Project Проект Angular Universal состоит из API базовой платформы и окружающих инструментов, которые позволяют разработчикам выполнять рендеринг (или предварительный рендеринг) приложений Angular на стороне сервера.

Для начала мы будем устанавливать пакет angular / platform-server и пакет angular / animations. Оба необходимы для правильной работы сервера платформы. Сервер платформы будет предоставлять серверный рендеринг.

Запустите приведенную ниже команду в своем терминале, чтобы установить зависимости, необходимые для рендеринга на сервере вашего приложения Angular:

$ npm install --save @ angular / platform-server @ angular / animations

После успешной установки пакетов с помощью NPM откройте ./src/app.modules.ts и внесите следующие изменения в объявление BrowserModule:

@NgModule ({... import: [BrowserModule.withServerTransition ({appId: 'blogist'})], ...})

В приведенном выше коде мы добавили метод withServerTransition в модуль BrowserModule, и там мы передали appId, который совпадает с именем блогиста приложения. Это дополнение «настраивает приложение на основе браузера для перехода от приложения, отображаемого на сервере, если оно присутствует на странице».

Следующее, что мы сделаем, это создадим модуль сервера приложений. Создайте новый файл ./src/app/app-server.module.ts

импортировать {NgModule} из '@ angular / core'; import {AppModule} из './app.module'; import {AppComponent} из './app.component'; импортировать {ServerModule} из '@ angular / platform-server'; @NgModule ({import: [ServerModule, AppModule,], начальная загрузка: [AppComponent]}) класс экспорта AppServerModule {}

Это базовый модуль Angular, который будет действовать как наш серверный модуль. Самое важное, что следует отметить в приведенном выше примере, - это то, что мы импортируем наш модуль AppModule в модуль сервера, поэтому теперь он будет частью модуля AppServerModule. Этот модуль будет там, где мы будем загружать наше приложение с сервера.

Добавление заголовка и мета-тегов в наше приложение Angular
Последнее, что мы добавим в приложение, - это поддержка метатегов и заголовков на каждой странице. С Angular Universal сделать это очень легко.

Откройте файл ./src/app/blog/posts.component.ts и выполните следующие действия:

Импортируйте мета и заголовок из пакета @ angular / platform-browser:

import {Meta, Title} из '@ angular / platform-browser';

Теперь в методе конструктора добавьте следующие строки кода:

конструктор (meta: Meta, title: Title) {this.posts = this.postsData (); // Устанавливает <title> </ title> title.setTitle ('Blogist'); // Устанавливает тег <meta> для страницы meta.addTags ([{name: 'author', content: 'Blogist'}, {name: 'description', content: 'Это описание.'},]) ; }

Приведенный выше код позволяет установить заголовок для каждой страницы, которую вы создаете, и они будут предварительно обработаны с использованием Angular Universal. Это позволяет вам лучше контролировать мета и заголовок различных страниц.

Создание сервера Express, чтобы сделать ваше приложение для Angular SEO дружественным
Давайте создадим экспресс-сервер. Это в основном позволит серверную визуализацию страницы.

Создайте новый файл в ./src/server.ts и затем добавьте содержимое ниже:

импорт 'отражать-метаданные'; импорт 'zone.js / dist / zone-node'; import {renderModuleFactory} из '@ angular / platform-server' import {enableProdMode} из '@ angular / core' import * как экспресс из 'express'; import {join} из 'path'; import {readFileSync} из 'fs'; import {AppServerModuleNgFactory} из '../dist/ngfactory/src/app/app-server.module.ngfactory' enableProdMode () const PORT = process.env.PORT || 4000 const DIST_DIR = join (__dirname, '..', 'dist') const app = express (); const template = readFileSync (join (DIST_DIR, 'index.html')). toString () app.engine ('html', (_, options, callback) => {const newOptions = {document: template, url: options. req.url}; renderModuleFactory (AppServerModuleNgFactory, newOptions) .then (html => callback (null, html))}) app.set ('views', 'src') app.set ('view engine', 'html' ) app.get ('*. *', express.static (DIST_DIR)) app.get ('*', (req, res) => {res.render ('index', {req})}) app. listen (PORT, () => {console.log (`Приложение прослушивает http: // localhost: $ {PORT}!`)});

В этом файле мы импортировали все пакеты, которые нам нужны для запуска нашего сервера Express. В частности, мы импортируем AppServerModuleNgFactory, файл, который еще не существует, но будет сгенерирован в процессе сборки.

Затем мы включаем ProdMode (), который просто включает производственный режим в нашем приложении. Мы также используем [renderModuleFactory] (https://angular.io/api/platform-server/renderModuleFactory) для анализа HTML-кода и визуализации страницы, которая загружалась на стороне сервера. Все остальное в коде связано с Express.

Следующее, что мы хотим сделать сейчас, это открыть наш файл ./src/tsconfig.app.json и добавить server.ts в раздел исключения файла.

"exclude": ["server.ts", ...]

Property Свойство exclude указывает список файлов, которые необходимо исключить из компиляции.

Также откройте файл ./tsconfig.json и добавьте приведенный ниже фрагмент к файлу в корне проекта прямо под свойством compilerOptions:

... "lib": ["es2016", "dom"]}, "angularCompilerOptions": {"genDir": "./dist/ngfactory", "entryModule": "./src/app/app.module# AppModule "}}

Gen GenDir - это то, куда все сгенерируется. EntryModule принимает путь нашего основного загрузочного модуля. #AppModule в конце пути - это имя экспортируемого класса.

Последний шаг - обновление свойства scripts в нашем файле ./package.json. Вам следует либо заменить, либо добавить это к ключам, уже имеющимся в свойстве scripts:

{... "scripts": {"prestart": "ng build --prod && ./node_modules/.bin/ngc", "start": "ts-node src / server.ts"}, ...}

У нас есть команды, зарегистрированные для сценариев запуска и предварительного запуска в файле ./package.json. Поскольку мы добавили pre к имени start , оно будет запускаться автоматически перед вызовом сценария start .

Тестирование нашего дружественного к SEO приложения Angular 4

Когда вы закончите вносить эти изменения в приложение, перейдите в терминал и выполните следующую команду:

$ npm run start

Это запустит сценарий предварительного запуска, который содержит команды ng build --prod && ./node_modules/.bin/ngc, а затем запустит запуск сценария, который содержит команду ts-node src / server.ts. Как только команды завершены, вы должны увидеть вывод, близкий к этому, на вашем терминале:

Когда вы заходите на страницу сейчас, вы все равно должны видеть тот же результат, что и раньше. Однако, когда вы просматриваете исходный код, вы должны увидеть полностью визуализированный HTML. Это будет то, как поисковые роботы увидят страницу.

Заключение

В этой статье мы выяснили, как сделать ваше приложение Angular 4 Single Page Application (SPA) SEO удобным с помощью Angular 4 Universal. Надеюсь, вы узнали что-то одно или два, и страх перед плохой оптимизацией SEO больше не помешает вам использовать Angular 4 для ваших приложений.

Исходный код этого приложения можно найти на GitHub , Пометьте и оставьте отзыв, проблемы или комментарии. Если у вас также есть какие-либо вопросы, не стесняйтесь оставлять их ниже.

Вход