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?

Googleも開けない16年前の初代iPadを、家族用レシピ端末として復活させた

0
Last updated at Posted at 2026-10-29

はじめに

2010年発売の初代iPadが自宅に眠っていました。

すっかり放電していたのですが、充電してみると無事に起動。

しかし、SafariでGoogleやYahoo! JAPANを開こうとしても表示されません。

せっかくなので、料理のレシピを見る端末として再利用できないかと考えました。

初代iPadの最終OSはiOS 5.1.1。現代のWebサイトを閲覧するには、あまりにも古い環境です。

Linuxに入れ替えることも考えましたが、タッチ操作やWi-Fiを含めて実用的に動かすのは難しそうです。

そこで発想を変えました。

「最新のWebサイトをiPadで開く」のではなく、「別のパソコンでレシピを取得して、古いiPadでも読めるHTMLに変換すればいいのでは?」

結果として、Chrome拡張機能(Braveでも動作)とNode.jsを使い、ワンクリックでレシピを初代iPadに送れる仕組みができました。

完成したもの

使い方は簡単です。

  1. Macのブラウザで、普段どおりGoogle検索する
  2. 気に入ったレシピのページを開く
  3. 拡張機能の「iPadに送る」ボタンを押す
  4. 初代iPadに材料と作り方が自動表示される

URLのコピーや貼り付けは不要です。

家族が使うものなので、できるだけ操作を少なくしました。

実際の表示

PXL_20261029_084204896.jpg
PXL_20261029_084211422.jpg

レシピ名、材料、作り方を大きな文字で表示します。

広告や余計なナビゲーションがないので、料理中に必要な情報だけを確認できます。

システム構成

Mac(Brave / Chrome)
    │
    │ Googleでレシピを検索
    ▼
レシピサイト
    │
    │ 拡張機能のボタンをクリック
    ▼
ブラウザ拡張機能(Manifest V3)
    │
    │ Recipe構造化データなどを抽出
    │ JSONをlocalhost:8000へPOST
    ▼
Node.js HTTPサーバー
    │
    ├─ current-recipe.json に保存
    │
    └─ 古いSafari向けHTMLを生成
              │
              │ 家庭内Wi-Fi / HTTP
              ▼
       初代iPad(iOS 5.1.1)
              │
              └─ 12秒ごとに更新を確認

使用したものは以下のとおりです。

項目 環境
表示端末 初代iPad(2010年)
OS iOS 5.1.1
サーバー iMac / macOS Sonoma
ブラウザ Brave(Chromeでも利用可能)
拡張機能 Manifest V3
サーバー Node.js
保存形式 JSON
通信 家庭内LANのHTTP

Reactなどのフレームワークは使用していません。

Node.jsも標準モジュールだけで動くので、npm install は不要です。

1. まずは古いSafariでHTMLを表示できるか検証

最初にMacで簡単なHTMLファイルを用意し、PythonのHTTPサーバーで配信しました。

python3 -m http.server 8000

初代iPadのSafariで、MacのIPアドレスを指定します。

http://192.168.1.xxx:8000/

すると、問題なく表示されました。

ここで、初代iPadでもシンプルなHTMLなら十分に使えることが確認できました。

2. レシピを取得するChrome拡張機能

次に考えたのは、レシピの取得方法です。

最初は、Webアプリ内にGoogle検索を組み込もうとしました。

しかし、Google検索をiframeで埋め込むことには制限があります。また、独自の検索APIを使うほどのシステムでもありません。

そこで、ブラウザ拡張機能を使うことにしました。

Google検索はいつもどおり利用し、レシピのページを開いた状態でボタンを押すだけです。

拡張機能では chrome.scripting.executeScript() を利用して、現在のページからレシピ情報を抽出します。

送信処理の主要部分は次のようになっています(エラー処理などは省略)。

chrome.action.onClicked.addListener(async (tab) => {
  const results = await chrome.scripting.executeScript({
    target: { tabId: tab.id },
    func: extractRecipeFromPage
  });

  const recipe = results[0].result;

  await fetch('http://127.0.0.1:8000/api/recipe', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(recipe)
  });
});

Recipe構造化データを利用

多くのレシピサイトには、schema.org/Recipe に基づいたJSON-LDが埋め込まれています。

例えば、次のようなデータです。

{
  "@context": "https://schema.org",
  "@type": "Recipe",
  "name": "肉じゃが",
  "recipeYield": "4人分",
  "recipeIngredient": [
    "じゃがいも 3個",
    "玉ねぎ 1個",
    "牛肉 200g"
  ],
  "recipeInstructions": [
    {
      "@type": "HowToStep",
      "text": "材料を食べやすい大きさに切る"
    },
    {
      "@type": "HowToStep",
      "text": "鍋で材料を炒める"
    }
  ]
}

これなら、サイトごとに複雑なHTMLを解析しなくても、材料や作り方を取得できます。

実装では、ページ内の

document.querySelectorAll(
  'script[type="application/ld+json"]'
)

からJSON-LDを取得し、@graph などの入れ子構造もたどって Recipe 型を探しています。

3. すべてのレシピサイトで動くわけではない

実際に試してみると、サイトによって結果が違いました。

レシピサイト 結果
クックパッド OK
キユーピー3分クッキング OK
クラシル OK
楽天レシピ OK
キッコーマン 初回NG → 対応
デリッシュキッチン 初回NG → 抽出処理を追加

キッコーマンの一部のレシピ記事では、期待したRecipe構造化データを取得できませんでした。

そこで、見出しや手順番号を使って本文から抽出する処理を追加しました。

デリッシュキッチンについても、「材料」「手順」などの表示テキストを解析する専用処理を追加しています。

ただし、この方式はサイトのHTML構造が変更されると動かなくなる可能性があります。

すべてのレシピサイトに対応することは目指さず、家族がよく使うサイトから順番に対応する方針です。

4. 初代iPad向けのHTML

iPad側では、最新のJavaScriptフレームワークを使いません。

Node.js側でHTMLを生成し、Safariはそれを表示するだけにしています。

CSSもシンプルです。

body {
  font-family: Arial, sans-serif;
  color: #222;
  background: #fffdf7;
  margin: 0;
  padding: 18px 28px;
  font-size: 30px;
  line-height: 1.65;
}

h1 {
  font-size: 40px;
  line-height: 1.4;
}

h2 {
  font-size: 36px;
}

最初は本文25pxでしたが、少し離れたところからでも読みやすいように30pxに変更しました。

自動更新の仕組み

Macから新しいレシピを送信した際、iPad側で毎回Safariを更新するのは面倒です。

そこで、12秒ごとにサーバーへ問い合わせる仕組みにしました。

setInterval(update, 12000);

update() 内では、古いSafariでも利用できる XMLHttpRequest を使って /api/version を取得します。

現在表示しているレシピのバージョンと異なれば、ページを再読み込みします。

WebSocketなどは使っていません。

初代iPadでも、この仕組みは問題なく動作しました。

5. iMacでサーバーを自動起動

家族が使う以上、毎回ターミナルで

node server.js

を実行してもらうわけにはいきません。

そこで、macOSの launchd を利用して、ログイン時にNode.jsサーバーが自動起動するようにしました。

LaunchAgentには次の設定を使用しています。

<key>RunAtLoad</key>
<true/>

<key>KeepAlive</key>
<true/>

これでログイン時に自動起動し、プロセスが終了した場合も再起動を試みます。

実際には、インストール用スクリプトを用意して、

zsh install_autostart.command

で登録できるようにしました。

動作確認には、次のURLを使用します。

http://localhost:8000/health

OK と表示されればサーバーが稼働しています。

なお、iMacがスリープしている間は利用できませんが、復帰すれば通常は利用を再開できます。

6. セキュリティと制限事項

初代iPadはすでにセキュリティ更新が終了しています。

今回の仕組みは、信頼できる家庭内LANでの利用を前提としています。

  • サーバーをインターネットに公開しない
  • ルーターでポート転送を設定しない
  • iPadでは銀行や個人情報を扱うサイトにアクセスしない
  • レシピの送信APIはローカルホストからのアクセスに限定する

また、レシピの本文は家庭内での個人的な閲覧用として扱い、取得したコンテンツを公開・再配布しないようにしています。

現時点では写真の表示やお気に入り機能には対応していません。

おわりに

最初は「古いiPadでレシピサイトくらい見られないかな」という程度の思いつきでした。

しかし、初代iPadそのものを現代のWebに対応させようとするのではなく、Webの情報を古い端末に合わせて変換するという方法で、思いのほか実用的なものができました。

最新のブラウザやフレームワークを動かす必要がないので、16年前の端末でも十分に役立ちます。

現在は基本機能が完成し、家族に実際に使ってもらっている段階です。

使い勝手を確認しながら、必要があれば改善していこうと思っています。

古いハードウェアでも、役割を限定すればまだまだ使えるものですね。

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?