Skip to content

feat: support custom OpenRouter base URL via OPENROUTER_BASE_URL #3104

Open
guangyang1206 wants to merge 1 commit intoonlook-dev:mainfrom
guangyang1206:feat/custom-llm-base-url
Open

feat: support custom OpenRouter base URL via OPENROUTER_BASE_URL #3104
guangyang1206 wants to merge 1 commit intoonlook-dev:mainfrom
guangyang1206:feat/custom-llm-base-url

Conversation

@guangyang1206
Copy link
Copy Markdown

@guangyang1206 guangyang1206 commented Apr 26, 2026

Summary

Closes #3048

Adds support for a custom OpenRouter API base URL, making it easy to use Onlook
with a proxy or self-hosted OpenAI-compatible backend without modifying source code.

What changed

packages/ai/src/chat/providers.ts

  • Added getOpenRouterBaseUrl() helper that reads the optional OPENROUTER_BASE_URL env var
  • Passed resolved base URL to createOpenRouter({ baseURL }) when set
  • Default behaviour is unchanged when env var is absent

apps/web/client/.env.example

  • Documented the new OPENROUTER_BASE_URL optional variable

Why

Users running Onlook behind a proxy, in air-gapped environments, or with a
self-hosted endpoint have no way to redirect OpenRouter calls without patching code.
A single env var covers all these scenarios.

  • Bug fix
  • New feature
  • Documentation
  • Refactor
  • Other (please describe):

Testing

  1. No env var set — behaviour unchanged ✅
  2. Set OPENROUTER_BASE_URL=https://your-proxy.example.com/api/v1 — requests routed to custom URL ✅
  3. tsc --noEmit in packages/ai should pass ✅

Checklist

  • No breaking changes (env var is optional)
  • .env.example updated with documentation
  • No new dependencies added

Summary by CodeRabbit

  • New Features
    • Added optional OPENROUTER_BASE_URL environment variable configuration, enabling users to override the default OpenRouter API base URL with a custom endpoint while maintaining full backward compatibility with existing setups.

…env var

Closes onlook-dev#3048

When self-hosting Onlook or routing requests through a custom proxy,
the OpenRouter endpoint is now configurable via the OPENROUTER_BASE_URL
environment variable.

Lookup order:
  1. OPENROUTER_BASE_URL env var (explicit override)
  2. Default OpenRouter endpoint (https://openrouter.ai/api/v1)

Updated apps/web/client/.env.example to document the new optional var.
@vercel vercel Bot temporarily deployed to Preview – docs-onlook April 26, 2026 12:23 Inactive
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs-onlook Skipped Skipped Apr 26, 2026 0:23am

Request Review

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 26, 2026

@guangyang1206 is attempting to deploy a commit to the Onlook Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 26, 2026

📝 Walkthrough

Walkthrough

Environment configuration and provider implementation added to support custom OpenRouter API base URLs. The .env.example documents the optional OPENROUTER_BASE_URL variable, while providers.ts implements retrieval and integration of this override into the OpenRouter client initialization.

Changes

Cohort / File(s) Summary
Environment Configuration
apps/web/client/.env.example
Documented optional OPENROUTER_BASE_URL environment variable with example value and note that the default applies when unset.
OpenRouter Provider Implementation
packages/ai/src/chat/providers.ts
Added getOpenRouterBaseUrl() function to retrieve the base URL override and integrated it into OpenRouter client creation options.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A rabbit's whiskers twitch with cheer,
Custom URLs now crystal clear!
OpenRouter bends to our will,
Self-hosted dreams we soon fulfill,
Base paths dance at our command! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive The PR addresses the base URL customization requirement from #3048 but only implements OPENROUTER_BASE_URL while the issue requests both OPENAI_BASE_URL and ANTHROPIC_BASE_URL. Clarify whether this PR is partial implementation for OpenRouter only or if OPENAI/ANTHROPIC base URLs are out of scope for this PR and covered by separate issues.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding support for a custom OpenRouter base URL via environment variable.
Description check ✅ Passed The PR description is comprehensive and follows the template structure with clear sections covering summary, what changed, why, testing steps, and a completion checklist.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing custom OpenRouter base URL support as defined in the PR objectives; no unrelated modifications are present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/ai/src/chat/providers.ts (1)

58-60: Optional: trim whitespace from the env var.

If a user accidentally adds trailing whitespace or a trailing newline to OPENROUTER_BASE_URL, the value will be passed verbatim to createOpenRouter, producing puzzling request failures. A small .trim() plus emptiness check makes the helper more forgiving:

♻️ Proposed refinement
 function getOpenRouterBaseUrl(): string | undefined {
-    return process.env.OPENROUTER_BASE_URL || undefined;
+    const value = process.env.OPENROUTER_BASE_URL?.trim();
+    return value ? value : undefined;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ai/src/chat/providers.ts` around lines 58 - 60, The helper
getOpenRouterBaseUrl should trim whitespace and return undefined for empty
strings to avoid passing trailing whitespace/newlines to createOpenRouter;
update getOpenRouterBaseUrl to read process.env.OPENROUTER_BASE_URL, call
.trim() (if defined), and return undefined when the trimmed value is an empty
string so callers like createOpenRouter receive a clean URL or undefined.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/web/client/.env.example`:
- Around line 11-13: The env schema is missing the OPENROUTER_BASE_URL variable
used by packages/ai/src/chat/providers.ts; update the server/client env schema
in env.ts to include OPENROUTER_BASE_URL as an optional URL (use
z.string().url().optional()) alongside OPENROUTER_API_KEY, and add
OPENROUTER_BASE_URL to the runtimeEnv block so it is validated at build time.

---

Nitpick comments:
In `@packages/ai/src/chat/providers.ts`:
- Around line 58-60: The helper getOpenRouterBaseUrl should trim whitespace and
return undefined for empty strings to avoid passing trailing whitespace/newlines
to createOpenRouter; update getOpenRouterBaseUrl to read
process.env.OPENROUTER_BASE_URL, call .trim() (if defined), and return undefined
when the trimmed value is an empty string so callers like createOpenRouter
receive a clean URL or undefined.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9a31e07f-4fad-4635-9395-862eb63974d7

📥 Commits

Reviewing files that changed from the base of the PR and between a242be5 and a6c4b0d.

📒 Files selected for processing (2)
  • apps/web/client/.env.example
  • packages/ai/src/chat/providers.ts

Comment on lines +11 to +13
# Optional: override the OpenRouter API base URL (e.g. for self-hosted proxies or custom endpoints)
# Defaults to https://openrouter.ai/api/v1 when unset
# OPENROUTER_BASE_URL="https://your-proxy.example.com/api/v1"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Locate env schema file(s) and check how OPENROUTER_API_KEY is declared
fd -t f 'env.ts$' apps packages | head -50
echo '---'
rg -n 'OPENROUTER_API_KEY' --type=ts -C2
echo '---'
rg -n 'OPENROUTER_BASE_URL' --type=ts -C2

Repository: onlook-dev/onlook

Length of output: 4122


🏁 Script executed:

#!/bin/bash
# Check the full env.ts file to see if OPENROUTER_BASE_URL is declared
echo "=== apps/web/client/src/env.ts ===" 
cat apps/web/client/src/env.ts | head -150

Repository: onlook-dev/onlook

Length of output: 5928


Add OPENROUTER_BASE_URL to the env schema for consistency.

OPENROUTER_API_KEY is declared in the server schema at apps/web/client/src/env.ts:36, but the new OPENROUTER_BASE_URL variable (consumed at packages/ai/src/chat/providers.ts:59) is missing from the schema. Add it as optional to match the usage pattern:

OPENROUTER_BASE_URL: z.string().url().optional(),

Also add it to the runtimeEnv section for proper validation at build time.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/client/.env.example` around lines 11 - 13, The env schema is missing
the OPENROUTER_BASE_URL variable used by packages/ai/src/chat/providers.ts;
update the server/client env schema in env.ts to include OPENROUTER_BASE_URL as
an optional URL (use z.string().url().optional()) alongside OPENROUTER_API_KEY,
and add OPENROUTER_BASE_URL to the runtimeEnv block so it is validated at build
time.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] Custom OPENAI_BASE_URL

1 participant