Sign-up, sign-in links, password resets, verification and email change emails now answer 429
TOO_MANY_REQUESTS. Desktop, mobile and the web login pages show it translated, Electron sign-up
shows its refusals at all, and mobile's reset mail from settings no longer claims it was sent.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A sign-in link for a 2FA account now comes back with ?error=TWO_FACTOR_REQUIRED, and provider
sign-ins pass errorCallbackURL, so account_not_linked returns to the app instead of the API's
error page. The web app and the login page show the reason, translated, and drop the parameter.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Choosing SN Pro as the global or content font did nothing on the web:
the production Tailwind pass rewrites the whole stylesheet and drops the
font CSS's relative url()s, so no font file was emitted and each request
got index.html. The font CSS is now imported from JS on its own, in the
renderer and the SSR client.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The user provider writes the session user in an effect of the same
commit that mounts the login page's avatar, and jotai 3 subscribes
after that commit, so the avatar kept reading no user and the signed-in
view never showed who was signed in. Read whoami with
useAtomValueRawSync.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The share preview worker cached its font list on the first image even
when loading the CJK font from R2 had failed, so after one R2 error the
worker rendered every preview without it until it restarted, leaving
Chinese and Japanese titles without glyphs in images cached for an hour.
Keep the list only once the CJK font is in it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The landing site and the share pages told the browser not to allow zoom
(user-scalable=no, maximum-scale=1), so people with low vision couldn't
pinch to zoom the home, download, pricing or share pages, which fails
WCAG 1.4.4. Keep the device width and initial scale only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every entry image on the share pages had tabIndex 1, so the first Tab
presses went through all images before the header, the Follow button
and the links, and the images had no alt text, so screen readers read
their URLs. The placeholder's aspect ratio was also inverted. Make only
clickable images focusable in the normal order, give the illustrations
an empty alt and use width over height.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A list keeps the ids of feeds that were deleted since, which the API
returns no data for, and the shared list page read the missing feed's
id and crashed with an application error. Show only the feeds that
still exist.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Share pages only recognized not found errors from ofetch, but the API
client throws FollowAPIError, so missing feeds, lists and profiles were
served with status 200 and indexed as soft 404s. In the browser the feed
page then kept spinning and the list page stayed blank, also when the
API failed for another reason.
Treat API 404s as not found and pass other API statuses on, and show
the not found page or a translated retry view on the feed and list
pages, sharing the profile page's view.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Feed, list and user preview images embedded any image/* response as
the avatar. Feeds without an image use their site's favicon, often an
ICO file, which the renderer can't draw, so the whole preview failed
and the route answered 404; feeds like Hacker News had no preview when
shared. Any API failure was also reported as 404.
Embed only formats the renderer draws, render again with the initials
if the avatar still fails, and answer 404 only for a missing feed or
list, letting other API failures surface as server errors.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The worker build intentionally bundles all dependencies (noExternal: ["**"])
for Cloudflare Workers. Set inlineOnly: false to suppress the error that
causes the build to exit with code 1.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* chore(infra): migrate desktop web from Vercel to Cloudflare Workers
Replaces separate Vercel deployments (follow SPA + follow-external-ssr) with unified Cloudflare Workers + Assets deployment. Implements meta tag injection, OG image generation, and environment variable management in Hono-based Worker. Adds GitHub Actions CI/CD for automatic deployment on push to dev/main branches.
- Replace Fastify with Hono for Cloudflare Workers compatibility
- Create Worker entry point with SSR routes and SPA fallback
- Add AsyncLocalStorage-based request context shim
- Implement WASM-based OG image rendering with R2 font storage
- Split SPA and SSR routing: /share/* and auth routes use SSR, others fallback to SPA
- Add Cloudflare wrangler configuration with dev/prod environments
- Create GitHub Actions workflow for automated deployments
- Add build scripts for font data and WASM patching
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(ssr): exclude worker files from typecheck and fix tsdown config
Worker-specific files (*.worker.ts) use Cloudflare Workers types and
generated modules that aren't available during the main tsc typecheck.
Exclude them from tsconfig since they're only used via tsdown aliases.
Also fix broken path.resolve reference in tsdown.worker.config.ts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* chore: update workspace dependencies
- bump dependencies across desktop, mobile, ssr, and internal packages
- refresh pnpm lockfile
- apply type compatibility fixes required by upgraded packages
* fix(ssr): prevent tsdown CI warning from failing build
- set inlineOnly to false in tsdown config
* style: format files for CI prettier check
- apply prettier formatting to files reported by format:check
* fix(mobile): downgrade reanimated for rn 0.79 ios build
Remove the following modules and features:
- Referral/invitation system across desktop, mobile, and SSR
- AI memory management (SaveMemoryCard, ManageMemoryCard, UserMemorySection)
- Daily reward claim and reward description modal
- Activity points and level display in wallet
- Related query files and imports
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
- Enhanced header button styles for better visual consistency.
- Increased width of the card in the forget password and reset password pages for improved layout.
- Removed unnecessary button component from the card title for a cleaner design.
Signed-off-by: Innei <tukon479@gmail.com>