When Mozilla shut down Pocket in July 2025, I lost my favorite tool. Worse, none of the English alternatives (Instapaper, Readwise, Matter, Raindrop) had Japanese UI, and their article extraction was mediocre on Japanese pages.
So I built one. It's called Readbox — Japanese-first, English-too, read-later as a PWA. Here's what I learned shipping it.
The stack
- Next.js 15 App Router + TypeScript strict (no
any) - Supabase (Postgres + Auth + RLS)
- Stripe (JPY + USD prices, locale-routed)
- Tailwind CSS
- Service Worker for PWA install + offline read
Three things that bit me
1. Article extraction on Vercel serverless
First attempt: Mozilla Readability + jsdom. Doesn't bundle on Vercel because of ESM compatibility issues and the 50MB serverless function size limit. I tried 6 approaches — Webpack externals, dynamic imports, edge runtime — none worked cleanly.
Ended up using Jina Reader, which returns clean Markdown/HTML from any URL. Trade-off: third-party dependency, rate limits at scale. But it works today, and it's free.
2. Storing article body on-device
I didn't want to host millions of articles' worth of HTML on Supabase (cost + privacy). Solution: extracted HTML lives in the browser's IndexedDB only (via Dexie); only metadata (URL, title, tags, read status) syncs to the server.
Trade-off: cross-device sync of body content doesn't work seamlessly. Acceptable for a "read it later" workflow where you usually read on the device you saved on.
3. i18n routing — the silent sitemap killer
For Japanese + English from one codebase: app/[locale]/ segment with /en prefix for English (default Japanese has no prefix, to preserve old URLs).
Middleware detects cookie / Accept-Language and redirects accordingly.
The gotcha (cost me a launch-day hour): middleware matcher excludes _next, api, image extensions — but if you forget .xml/.txt/.webmanifest, sitemap.xml and robots.txt get rewritten to /ja/sitemap.xml (which doesn't exist as a route → 404).
Fix:
export const config = {
matcher: [
'/((?!api|_next|.*\\.(?:xml|txt|webmanifest|svg|png|jpg|jpeg|gif|webp|ico)$).*)',
],
};
If you do i18n routing with metadata routes (sitemap/robots/manifest), put this in your test plan.
Where Readbox is now
Live with paid plans (¥450/mo, $3/mo, free for 100 articles). Pocket CSV import handles both 5-col legacy and 6-col new formats, up to 5,000 articles per batch.
- Japanese: https://readbox.dev-tools-hub.xyz/
- English: https://readbox.dev-tools-hub.xyz/en
If you migrated from Pocket, I'd love to hear what your read-later workflow looks like and what made you pick whatever you picked.
<!--
Publish 手順(しょうた手動、2 コマンド)
このファイル全体を
C:/job/S-hub/dev-to/articles/readbox-en-launch.mdにコピー
(上の HTML コメントブロック<!-- ... -->を含めて全文コピーで OK、
Dev.to の Markdown レンダリングは HTML コメントを無視するので
公開記事には表示されない。気になる場合はコピー後に削除)publish.mjs を実行(DEVTO_API_KEY を env で渡す):
cd C:/job/S-hub/dev-to
DEVTO_API_KEY=<あなたの devto API key> node publish.mjs
期待動作:
- publish.mjs が articles/ 配下の .md を順次スキャン
- 本記事 frontmatter の
devto_id: nullを見て draft 作成 → devto_id 書き込み - publish_date "2026-05-28" が today (5/28) と一致するので即 published 化
- 公開後、コンソールに
Published!+ 公開 URL が出力
- 公開された Dev.to URL を秘書 (3zzd1isy) に共有 → SNS 拡散発注(X/Bluesky/Threads の 5/29 JP slot に URL 添付)
補足
- canonical_url は
null(Dev.to をオリジナル扱い、Zenn は日本語独自記事として 並立、SEO 重複扱いされない) - tags は Dev.to 上限 4 個(javascript, nextjs, webdev, indiehackers)
- cover image (main_image) は任意。Dev.to は記事 URL から OG 画像を自動 pull
するので未設定 OK。設定する場合は readbox の OG エンドポイント
https://readbox.dev-tools-hub.xyz/en/opengraph-imageを main_image に - description (150 字以内) は Dev.to feed カード / 検索結果に表示される短文。 約 143 文字で設定済
トラブル対応
- API key 不正なら 401 で fail → key 確認
- tags 5 個以上だと 422 → tags を 4 個に切り詰め (既に 4 個で OK)
- title が既存記事と完全一致だと 422 → Dev.to の draft list 確認
- ネットワークエラー → publish.mjs は内部で retry 3 回 + 30s backoff、 それでもダメなら手動再実行で同じ devto_id を上書き更新可能 -->
Top comments (0)