1. >
  2. Blog
  3. >
  4. Nuxt.jsでリンクカードを簡単に実装する方法
2024年9月19日木曜日
Nuxt.jsでリンクカードを簡単に実装する方法

Nuxt.jsでリンクカードを簡単に実装する方法

Nuxt.jsを利用して、ブログ記事にリンクカードを埋め込む完全ガイド。open-graph-scraperの導入からLinkCardコンポーネントの作成、nuxt.config.tsとpackage.jsonの設定まで、すべての手順をカバーします。


はじめに

これまで、nuxtでtwitterとyoutubeを埋め込む方法を解説してきましたが、もう一つ欲しい機能がありました。 それが、リンクカードを埋め込む方法です。

この記事では、Nuxt.js@nuxt/content を使用して、ブログ記事にリンクカードを埋め込む方法を詳細に説明します。リンクカードは、外部リンクを視覚的に魅力的に表示するための重要なツールです。Vue.jsのスクリプトセットアップから、open-graph-scraperのインストール、そしてpackage.jsonへのコマンド追加まで、全ステップをカバーします。

リンクカード参考サイト

上からそれぞれ、Zennで使う場合、Astroで使う場合、Nuxt2で使う場合の方法の説明でした。 (画像を取得するのに苦労していましたが、上記Astroでの使い方のコードでやり方に気づきました。ありがとうございます)

いずれもNuxt3及び@nuxt/contentでの環境での説明はありませんでした。 というわけで以下で方法を説明します。

Nuxtでリンクカードを使う方法

Nuxtにリンクカードを埋め込む

Nuxt.jsと@nuxt/contentを使用してブログサイトに美しいリンクカードを埋め込む方法を紹介します。

上記の参考サイトリンクカードは以下の方法で表示させています

1. open-graph-scraperのインストール

まず、リンクカードに必要なOGP情報を取得するために、open-graph-scraper をインストールします。このパッケージは指定したURLからOGPデータを取得するのに役立ちます。

pnpmbash
pnpm add open-graph-scraper
yarnbash
yarn add open-graph-scraper
npmbash
npm install open-graph-scraper

また、Nuxt.jsのビルドツールとしてViteを利用するため、@vitejs/plugin-vue がインストールされていない場合は以下のコマンドを実行してインストールしてください。

pnpmbash
pnpm add @vitejs/plugin-vue
yarnbash
yarn add @vitejs/plugin-vue
npmbash
npm install @vitejs/plugin-vue

2. LinkCard.vueコンポーネントの作成

次に、app/components/content/LinkCard.vue ファイルを作成し、以下のコードを貼り付けます。このコンポーネントは、指定されたURLからOGPデータを取得し、それを基にリンクカードを表示します。

LinkCard.vuevue
<script setup lang="ts">
import { onMounted, ref } from "vue";
const props = defineProps({
  propsUrl: String,
  title: String,
  siteUrl: String,
  description: String,
});

// 環境変数を取得
const isDev = import.meta.env.VITE_APP_ENV === "development";

// リアクティブなデータとしてogpDataを定義
const ogpData = ref(null);

if (isDev) {
  // dev時
  onMounted(async () => {
    try {
      const data = await $fetch(`/api/ogp?url=${encodeURIComponent(props.propsUrl)}`);
      console.log("APIレスポンス:", data);
      ogpData.value = data;
    } catch (error) {
      console.error("Fetch error:", error);
    }
  });
} else {
  // generate時
  const { data, error } = await useFetch(
    `/api/ogp?url=${encodeURIComponent(props.propsUrl)}`
  );
  if (error.value) {
    console.error("Fetch error:", error.value);
  } else {
    ogpData.value = data.value;
  }
}
</script>
<template>
  <div class="link-card" v-if="ogpData">
    <a :href="propsUrl" target="_blank" rel="noopener">
      <div class="link-card-content">
        <div class="sm:basis-1/4 tb:basis-5/7 self-center">
          <img :src="ogpData.ogImage?.[0]?.url || '/img/ogp.png'" alt="OG Image" />
        </div>
        <div class="sm:(pt-2 flex-grow-2) tb:pl-2">
          <h3 class="m-0 p-0 text-24px">{{ ogpData.ogTitle || props.title }}</h3>
          <p class="mt-1 mb-2 p-0 underline text-sm">{{ ogpData.ogUrl || props.siteUrl }}</p>
          <p class="m-0 p-0">{{ ogpData.ogDescription || props.description }}</p>
        </div>
      </div>
    </a>
  </div>
  <div v-else>
    <p>Link Card Loading...</p>
  </div>
</template>
<style scoped lang="scss">
.link-card {
  border: 1px solid #ddd;
  padding: 16px;
  border-radius: 8px;
  transition: box-shadow 0.3s;
  a {
    text-decoration: none;
    &::after {
      content: none;
    }
  }
}
.link-card img {
  max-width: 100%;
  height: auto;
  display: block;
}
.link-card:hover {
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.link-card-content {
  text-align: left;
  display: flex;
}
.link-card-content {
  @screen at-sm {
    flex-direction: column;
    align-self: start;
  }
  @screen tb {
    flex-direction: row;
    align-self: center;
    & h3 {
      @apply text-h4_sm line-height-h3;
    }
  }
}
</style>

このコンポーネントは、OGP(Open Graph Protocol)データを取得し、リンクカードとして表示します。開発環境と本番環境で異なる動作をするように設計されています。スタイルはuno.cssを使用しています。お好みの方法でカスタマイズしてください。

3. nuxt.config.tsの設定

nuxt.config.ts ファイルに以下の設定を追加します。

nuxt.config.tsts
import vue from '@vitejs/plugin-vue'

export default defineNuxtConfig({
  // ... 他の設定

  vite: {
    plugins: [
      vue({
        template: {
          customElement: true,
        },
      }),
    ],
    define: {
      'import.meta.env.VITE_APP_ENV': JSON.stringify(process.env.VITE_APP_ENV),
    },
  },
})

この設定により、Vueのカスタム要素のサポートが有効になり、環境変数 VITE_APP_ENV が定義されます。

以上の手順で、Nuxt.jsプロジェクトにリンクカードを埋め込む準備が整いました。LinkCard コンポーネントを使用することで、美しいリンクカードをブログ記事に簡単に追加できます。

使用例:

  • mdファイルに埋め込む場合
Inline Componentsmd
::link-card{propsUrl="https://exanple.com"}
::

或いは、Block Components形式で、
::link-card
---
propsUrl: "https://exanple.com"
---
::
  • vueファイルに埋め込む場合
vue
<template>
  <LinkCard
    propsUrl="https://example.com"
  />
</template>

このコンポーネントを使用することで、指定したURLのOGPデータを自動的に取得し、スタイリングされたリンクカードとして表示します。

4.環境変数の設定

.envファイルに、VITE_APP_ENV 環境変数を設定します。

.envbash
VITE_APP_ENV='development'

さらに、.env ファイルの名称を変更します。

bash
mv .env .env.local
なぜ.env.localに移行するのか?通常、.env ファイルはプロジェクト内で環境変数を定義するために使用されますが、.env.local ファイルを使うと、開発チーム全体に共有せずに、ローカルの設定や機密情報を管理できます。`.env.local は、個々の開発者がローカル環境専用の設定を持つために適しています。例えば、デバッグ用のフラグや、個別のAPIキーなどを .env.local に入れておくことで、プロジェクトの他の開発者に影響を与えずに安全に利用できます

https://nuxt.com/docs/guide/directory-structure/env#custom-file

5. package.jsonへのコマンド追加

最後に、開発と本番用のコマンドを package.json に追加します。これにより、開発と生成のプロセスがよりスムーズになります。

package.jsonjson
{
  "scripts": {
    "dev": "nuxi dev --dotenv --env.local -o",
    "generate": "nuxi generate"
  }
}

まとめ

この記事では、Nuxt.jsと@nuxt/contentを使ったリンクカードの実装方法と、VITE_APP_ENV環境変数を.env.localに移行して管理するメリットを詳しく説明しました。これにより、開発環境と本番環境での設定が適切に管理され、セキュリティも向上します。