0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.jsでGoogleの検索結果をAPIで取得して画面に表示するまで

Posted at

記事内容

Google検索で表示される画像のデータを取得してNext.jsのアプリの画面に表示するまでの方法

GCP上でAPIと検索エンジンの準備をする

流れとしては自分用の検索エンジンを作って、その検索結果を使うことになる。
https://plus-pm.jp/blog/search-rank-check-use-google-custom-search-api/
この記事に従ってGoogle Custom Search APIのプロジェクトの作成、APIキーの取得、APIの有効化、Custom Search Engine(自分用の検索エンジン)を作成する。

Google API Client Librariesを使ってAPIを叩く

JavaScriptを選択すると、以下Githubのページに飛ぶ。
https://github.com/google/google-api-javascript-client

READMEの通りに進めていく。
TypeScriptの場合は@types/gapiを使えば良いとのことなので、そっちを使っていく。

npm install --save @types/gapi

https://developers.google.com/identity/oauth2/web/guides/migration-to-gis?hl=ja
上記のページの通りgoogle-api-javascript-clientは既に非推奨であった。
以前まではGoogleログインプラットフォームライブラリとGoogleAPIクライアントライブラリを使っていたが、これから Google Identity Services ライブラリに移行するらしい。

READMEのOption 2を試してみると、headに以下のスクリプトタグを追加する必要があるので
Next.jsのHeadを使用して、layout.tsxに追加。

<script src="https://apis.google.com/js/api.js"></script>

このスクリプトをそのまま使うと、Next.jsの非同期スクリプトエラーが出るため、async属性を追加しました。

import Head from 'next/head';

const MyHead = () => {
  return (
    <Head>
      <script src="https://apis.google.com/js/api.js" async />
    </Head>
  );
};

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <Providers>
          <MyHead />
          <div>{children}</div>
        </Providers>
      </body>
    </html>
  );
}

最後に、googleapisとaxiosをインストールし、custom searchのURLに各種情報を入れてAPIを叩く。

npm install googleapis axios
"use client";

import styles from "./page.module.css";
import { useState } from "react";
import { Input, IconButton, SearchIcon } from "@/plugins/chakra-ui-modules";
import axios from "axios";
import { customsearch_v1 } from "googleapis";

export default function Vocabulary() {
  const [englishWord, setEnglishWord] = useState("");
  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) =>
    setEnglishWord(event.target.value);

  const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
    if (event.key === "Enter") {
      searchEnglishWord();
    }
  };
  const searchEnglishWord = async () => {
    searchImages();
  };

  const [images, setImages] = useState<string[]>([]);

  const searchImages = async () => {
    try {
      const API_KEY = process.env.NEXT_PUBLIC_GOOGLE_SEARCH_API_KEY;
      const CUSTOM_SEARCH_ENGINE_ID =
        process.env.NEXT_PUBLIC_CUSTOM_SEARCH_ENGINE_ID;

      const response = await axios.get(
        `https://www.googleapis.com/customsearch/v1?q=${englishWord}&cx=${CUSTOM_SEARCH_ENGINE_ID}&key=${API_KEY}&searchType=image`
      );

      const items = response.data.items as customsearch_v1.Schema$Result[];

      const imageUrls = items.map((item) => item.link || "");
      setImages(imageUrls);
    } catch (error) {
      console.error("データの取得中にエラーが発生しました:", error);
    }
  };

  return (
    <div>
      <div>
        <Input
          value={englishWord}
          onChange={handleChange}
          onKeyDown={handleKeyDown}
          placeholder="英単語を入力してください。"
        />
        <IconButton
          aria-label="SearchIcon"
          icon={<SearchIcon />}
          onClick={searchEnglishWord}
        />
      </div>
      <div>
        {images.map((imageUrl, index) => (
          <img
            key={index}
            src={imageUrl}
            alt={`image${index}`}
            className={styles.image}
          />
        ))}
      </div>
    </div>
  );
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?