作ったもの
開発者向けの無料Webツールを5つ作りました。全部ブラウザで使えて、登録不要です。
| ツール | 概要 |
|---|---|
| QRコード生成 | テキスト/URLからQRコード生成。PNG/SVG、カスタムカラー対応 |
| メール検証 | メールアドレスの形式、ドメイン、MXレコード、使い捨てメール検出 |
| AI要約 | Claude AIでテキストを段落/箇条書き/一文に要約。5言語対応 |
| スクリーンショット | 任意のURLのスクリーンショットを撮影。PNG/JPEG/WebP対応 |
| HTML→PDF | HTMLやURLをPDFに変換。A4/Letter、縦横選択可 |
技術スタック
- フロントエンド: Next.js 16 (App Router) + Tailwind CSS v4
- バックエンド: 各ツールの処理は個別のVercelプロジェクトにデプロイ
- AI: Claude API (Haiku 4.5) — 要約と商品説明文生成
- PDF/スクリーンショット: Puppeteer + @sparticuz/chromium (サーバーレス)
- QRコード: qrcode npm パッケージ
- メール検証: Node.js dns.promises (MXレコード確認)
アーキテクチャ
hookray.com (Next.js)
├── /tools/qrcode → qrcode-api.vercel.app に転送
├── /tools/screenshot → screenshot-api.vercel.app に転送
├── /tools/pdf → pdf-api.vercel.app に転送
├── /tools/email-validator → email-validation-api.vercel.app に転送
└── /tools/summarizer → summarizer-api.vercel.app に転送
フロントエンドとバックエンドを分離し、hookray.com側にプロキシAPIを置いてます。これにより:
- バックエンドのURLがブラウザに露出しない
- CORS問題を回避
- 各バックエンドを独立してスケール可能
プロキシの実装
// src/lib/tool-proxy.ts
export async function forwardToolRequest(request: Request, target: string) {
const body = await request.text();
const upstream = await fetch(target, {
method: "POST",
headers: { "Content-Type": request.headers.get("content-type") ?? "application/json" },
body,
});
return new NextResponse(await upstream.arrayBuffer(), {
status: upstream.status,
headers: { "Content-Type": upstream.headers.get("content-type") ?? "" },
});
}
Freemium制限の実装
各ツールに1日の無料使用回数制限を設けています。
// localStorage で使用回数を管理
function readUsage(toolSlug: string): UsageData {
const stored = localStorage.getItem(`hookray:usage:${toolSlug}`);
const data = JSON.parse(stored);
const today = new Date().toISOString().split("T")[0];
if (data.date !== today) return { count: 0, date: today }; // 日付変更でリセット
return data;
}
| ツール | 無料回数/日 |
|---|---|
| QRコード | 10回 |
| メール検証 | 5回 |
| AI要約 | 3回 |
| スクリーンショット | 3回 |
| PDF変換 | 5回 |
制限に達すると「Upgrade to Pro」が表示されます。認証・決済は未実装で、まずは制限UIだけ入れてユーザー反応を見る方針です。
サーバーレスでPuppeteerを動かすコツ
VercelのサーバーレスFunctionでPuppeteer(Chromium)を動かすのは少しハマりポイントがあります。
// next.config.ts — Chromiumバイナリをバンドルに含める
const nextConfig = {
serverExternalPackages: ["@sparticuz/chromium", "puppeteer-core"],
outputFileTracingIncludes: {
"/api/screenshot": ["./node_modules/@sparticuz/chromium/bin/**/*"],
},
};
// route.ts — Chromium起動設定
import chromium from "@sparticuz/chromium";
import puppeteer from "puppeteer-core";
chromium.setGraphicsMode = false;
const browser = await puppeteer.launch({
args: puppeteer.defaultArgs({ args: chromium.args, headless: "shell" }),
executablePath: await chromium.executablePath(),
headless: "shell",
});
ポイント:
-
headless: "shell"が必要(trueだと動かないことがある) -
setGraphicsMode = falseで不要なGPUレンダリングを無効化 -
outputFileTracingIncludesでBrotli圧縮されたChromiumバイナリを含める
SEO戦略
各ツールページにSEOメタデータを設定し、サイトマップにも含めています。
// 各ページにSEO用メタデータを自動生成
export function getToolMetadata(slug: ToolSlug): Metadata {
const tool = getToolBySlug(slug);
return {
title: tool.seoTitle, // "QR Code Generator — Free Online Tool | HookRay"
description: tool.seoDescription,
openGraph: { ... },
};
}
現在41ページがGoogleにインデックス申請済みです。「qr code generator free」「html to pdf converter」などの検索で上位表示を狙っています。
APIとしても使える
各ツールのバックエンドはRapidAPIにも登録済みで、プログラマティックに使えます。
まとめ
個人開発で「最初の1円」を稼ぐための実験として作りました。マーケティングが苦手なので、SEOとマーケットプレイス(Chrome Web Store、RapidAPI)の「プラットフォームの信頼を借りる」戦略で進めています。
フィードバックお待ちしています!
リンク
- ツール: https://hookray.com/tools
- GitHub: https://github.com/ShotaTanikawa
- RapidAPI: https://rapidapi.com/ShotaTanikawa