Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
16
Help us understand the problem. What is going on with this article?
@T0000N

vue-metaを用いたOGPやJSON-LD用のメタタグ生成

More than 1 year has passed since last update.

vue-meta
https://github.com/nuxt/vue-meta

・Title and Description
・OGP
・JSON-LD
を生成するにはvue-metaが便利。
弊社ではNuxtを使わず、Vue.jsで作っています。
Vue-metaはNuxtプロジェクトの中で開発しているのでVue.jsでは使えないと思っていたのですが、Vue.jsでも使えました😍

この記事を書いたときのバージョン

"vue": "^2.6.10",
"vue-meta": "^2.3.1",

インストール

npm install vue-meta --save

コードの変更箇所

// src/main.ts
import VueMeta from 'vue-meta';
Vue.use(VueMeta);
// Page.vue
import {metatag} from @/metatag/metatag.ts'
export default Vue.extend({
    data() {
        return {
            this.initialized = false;
            this.param = {hoge: ‘bar'}
        }
    },
    mounted() {
        // ここでAPI通信などの非同期処理を行う。
        this.initialized = true;
    },
    metaInfo() {
      return this.initialized ? metatag(this.param) : null; // this.initializedが変更されると検知してくれる😂
    },
});
// src/metatag/metatag.ts
const TITLE = サイト名;

export function metatag(params: any) {
  const description = `descriptionを書くよ ${JSON.stringify(params)}`;
  return {
    title: TITLE,
    meta: [
      {name: 'description', content: description},
      {property: 'twitter:card', content: 'summary'},
      {property: 'twitter:title', content: document.title},
      {property: 'twitter:site', content: '@anonymous'},
      {property: 'twitter:creator', content: '@anonymous'},
      {property: 'twitter:description', content: description},
      {
        property: 'twitter:image',
        content: 'https://FQDN/favicon256.jpg',
      },
      {property: 'og:title', content: document.title},
      {property: 'og:description', content: description},
      {property: 'og:type', content: 'website'},
      {property: 'og:url', content: location.href},
      {
        property: 'og:image',
        content: 'https://FQDN/favicon256.jpg',
      },
    ],
    script: [
      {
        type: 'application/ld+json',
        innerHTML: JSON.stringify(
          [{
            '@context': 'http://schema.org',
            '@type': 'Organization',
            'url': location.href,
            'logo': 'https://FQDN/favicon256.jpg',
          },
            {
              '@context': 'http://schema.org',
              '@type': 'WebSite',
              'name': document.title,
              'alternateName': description,
              'url': location.href,
            },
          ], null, 2,
        ),
      },
    ],
  };
}

vue-headという類似ライブラリを使っていたんですけど、
this.$emit(‘updateHead’);
というメソッドを非同期通信完了のタイミングで実行しなければならなかったのが辛かった・・・
また、JSON-LDの書き方がすごくスッキリしました。

これで最低限のOGPとGoogle対策ができました。
とはいえ、Twitter CardやGoogleに完全対応するには、DynamicRenderingやSSRが必要です。
Vue.jsで開発しているとSSR対応は難しいので、HeaderlessChrome(puppeteer)を使ったDynamicRenderingをやることにしました。
DynamicRenderingに関しては結構長い記事なので次回更新します。

16
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
T0000N
漫画を読んで生活しています。 過去はビッグデータ / IoT システムのITアーキテクトでした。 Java / Python / Javascriptを書いていることが多いです。 宜しくお願いします。
torico
マンガに関わるWEBサービスを軸に、面白いと思えることを企画・開発している会社です。オタク文化が好きな人は是非一緒に働きましょう! Python3 / Vue.js(TypeScript) / Flutterで開発中!

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
16
Help us understand the problem. What is going on with this article?