📖

静的なホームページで動的なお知らせ情報を表示する

2025/03/11に公開

静的な Web サイトでも動的なコンテンツを表示したいということがあるかもしれません。
今回はタイトルの通り「ホームページにお知らせ情報を表示する」というケースを例に、その方法を一つ実際のコードと合わせて紹介したいと思います。

※サンプルのホームページはこちらから確認できます。

概要

今回紹介するのはお知らせを Google スプレッドシートで管理し、JS でそのスプレッドシートを取得するという方法になります。
上記のサンプルホームページや以下に記載するコード例ではこちらのスプレッドシートを参照しています。(このスプレッドシートではアクセス権の設定で「リンクを知っている人全員」を「閲覧者」にしています。)

コード例

ディレクトリ構成

.
├── index.html
├── main.js
└── styles.css

index.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="styles.css" />
    <title>サンプル HP</title>
  </head>

  <body>
    <h1>サンプル HP</h1>
    <p>ここはサンプル HP です。</p> 
    <h2>お知らせ</h2>
    <table>
      <thead>
        <tr>
          <th>日付</th>
          <th>内容</th>
        </tr>
      </thead>
      <tbody id="newsTableBody"></tbody>
    </table>
    <script src="main.js"></script>
  </body>
</html>

styles.css

body {
  font-family: Arial, sans-serif;
  text-align: center;
}

h1 {
  margin-top: 20px;
}

table {
  width: 80%;
  margin: 20px auto;
  border-collapse: collapse;
}

th, td {
  border: 1px solid #333;
  padding: 10px;
}

th {
  background-color: #f4f4f4;
}

main.js

const newsSheelUrl =
  "https://docs.google.com/spreadsheets/d/1GERZZfWermZFOCgJZbRD6UiXKLDIwljxm0xBWdnz3Eo/gviz/tq?tqx=out:csv";

const parseCsv = (csvString) => {
  const rows = csvString.split("\n");
  return rows.map((row) => {
    const [date, content] = row.split(",").map((col) => col.slice(1, -1));
    return { date, content };
  });
};

(async () => {
  const newsTableBody = document.getElementById("newsTableBody");
  const response = await fetch(newsSheelUrl);
  const content = await response.text();

  parseCsv(content).reverse().forEach(({ date, content }) => {
    const tableRow = document.createElement("tr");
    const dateCell = document.createElement("td");
    dateCell.textContent = date;
    const contentCell = document.createElement("td");
    contentCell.textContent = content;
    tableRow.appendChild(dateCell);
    tableRow.appendChild(contentCell);
    newsTableBody.appendChild(tableRow);
  });
})();

解説

html と css については特に変わったことはしていないので割愛させていただきます。
今回肝となるのは main.js で、処理としては以下の通りです。

  1. スプレッドシートを CSV 形式で取得
  2. レスポンスをパース
  3. テーブルにセット

手順 1. では Google Apps Script や Google Sheets API ではなく、GoogleVisualization API を利用し、スプレッドシートの URL の末尾に /gviz/tq?tqx=out:csv を付けてリクエストするという方法を採用しています。先頭のシート以外を取得したい場合は、/gviz/tq?tqx=out:csv&sheet=<sheet_name> のようにクエリパラメータを追加してシートを指定することになります。

リクエストの結果、以下のようなレスポンスが返されるので後はそれを表示するだけです。(手順 2. 以降)

"2024/10/06","初めてのお知らせ"
"2024/10/07","二回目のお知らせ"
"2024/10/20","三回目のお知らせ"
"2025/03/08","四回目のお知らせ"

これにより、ホームページ側に変更を加えることなく最新のお知らせ情報を反映することができます。

cf.

注意点

スプレッドシートのアクセス権限の設定が大事

今回紹介した方法ではスプレッドシートの URL が丸わかりなので、例えばアクセス権の設定で「リンクを知っている人全員」を「編集者」にしてしまうと管理者の知らない内に編集されてしまうということが起こり得るので、必ず適切な設定になっていることを確認してください。

大抵のケースでは今回のように「リンクを知っている人全員」を「閲覧者」にすれば良いはずです。

大量のリクエストに対応しているかが不明

上記の通り、今回は GoogleVisualization API を利用していますが、公式ドキュメントを見てもリクエスト数の制限等に関する記述が見つけられませんでした。そのため大量にリクエストが発生した場合に、例えばリクエスト制限がかけられデータが取得できなくなるという可能性もあります。

Discussion