Skip to content

Claude (Anthropic) API blocked by browser CORS policy #1

Description

@jeffwright13

Summary
Selecting Claude as the provider and attempting to generate content fails with a CORS error. The Anthropic API does not return Access-Control-Allow-Origin headers, so browsers block the request before it reaches the API.

Error
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource
at https://api.anthropic.com/v1/messages.
(Reason: CORS header 'Access-Control-Allow-Origin' missing). Status code: 400.

Root cause
Krashen is a static site — API calls are made directly from the browser. Anthropic intentionally does not support browser-to-API CORS for api.anthropic.com. This is by design on their end; there is no workaround on the client side.

OpenAI and Google Gemini both allow direct browser requests and work correctly.

Current mitigation

  • Default provider changed to OpenAI (commit d0e41c6)
  • A warning is shown inline when Claude is selected: "Claude's API blocks browser requests (CORS). Works only via a local proxy."

Resolution options

  1. Cloudflare Worker proxy — a ~20-line worker forwards browser requests to api.anthropic.com and adds the required CORS headers. Free tier (100k req/day) is sufficient. Main app stays on GitHub Pages. Requires a Cloudflare account.
  2. Netlify Functions — move deployment from GitHub Pages to Netlify; API call goes through a serverless function that runs server-side. More platform lock-in.
  3. Accept the limitation — Claude stays in the selector with the warning; users who want Claude use one of the two options above or run locally with a real backend.

Notes

  • This issue does not affect hablabot (sibling repo) because that app uses OpenAI exclusively.
  • Running npm run serve locally does not fix this — CORS is enforced by the browser regardless of where the HTML is served from.
  • If Anthropic adds CORS support in the future, no code changes are needed; the existing llm.js Claude implementation is correct.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions