refactor(env): update NEXT_PUBLIC_API_URL to use 'auto' for better flexibility

This commit is contained in:
Abhimanyu Saharan
2026-03-03 02:40:28 +05:30
parent 2031f8dcd8
commit 0fe61e3e08
11 changed files with 74 additions and 33 deletions

View File

@@ -1,4 +1,5 @@
import { getLocalAuthToken, isLocalAuthMode } from "@/auth/localAuth";
import { getApiBaseUrl } from "@/lib/api-base";
type ClerkSession = {
getToken: () => Promise<string>;
@@ -39,11 +40,7 @@ export const customFetch = async <T>(
url: string,
options: RequestInit,
): Promise<T> => {
const rawBaseUrl = process.env.NEXT_PUBLIC_API_URL;
if (!rawBaseUrl) {
throw new Error("NEXT_PUBLIC_API_URL is not set.");
}
const baseUrl = rawBaseUrl.replace(/\/+$/, "");
const baseUrl = getApiBaseUrl();
const headers = new Headers(options.headers);
const hasBody = options.body !== undefined && options.body !== null;

View File

@@ -7,17 +7,18 @@ import { setLocalAuthToken } from "@/auth/localAuth";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { getApiBaseUrl } from "@/lib/api-base";
const LOCAL_AUTH_TOKEN_MIN_LENGTH = 50;
async function validateLocalToken(token: string): Promise<string | null> {
const rawBaseUrl = process.env.NEXT_PUBLIC_API_URL;
if (!rawBaseUrl) {
return "NEXT_PUBLIC_API_URL is not set.";
let baseUrl: string;
try {
baseUrl = getApiBaseUrl();
} catch {
return "Unable to resolve backend URL.";
}
const baseUrl = rawBaseUrl.replace(/\/+$/, "");
let response: Response;
try {
response = await fetch(`${baseUrl}/api/v1/users/me`, {

View File

@@ -0,0 +1,27 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import { getApiBaseUrl } from "./api-base";
describe("getApiBaseUrl", () => {
afterEach(() => {
vi.unstubAllEnvs();
});
it("returns normalized explicit URL", () => {
vi.stubEnv("NEXT_PUBLIC_API_URL", "https://api.example.com///");
expect(getApiBaseUrl()).toBe("https://api.example.com");
});
it("auto-resolves from browser host when set to auto", () => {
vi.stubEnv("NEXT_PUBLIC_API_URL", "auto");
expect(getApiBaseUrl()).toBe("http://localhost:8000");
});
it("auto-resolves from browser host when unset", () => {
vi.stubEnv("NEXT_PUBLIC_API_URL", "");
expect(getApiBaseUrl()).toBe("http://localhost:8000");
});
});

View File

@@ -1,11 +1,22 @@
export function getApiBaseUrl(): string {
const raw = process.env.NEXT_PUBLIC_API_URL;
if (!raw) {
throw new Error("NEXT_PUBLIC_API_URL is not set.");
const raw = process.env.NEXT_PUBLIC_API_URL?.trim();
if (raw && raw.toLowerCase() !== "auto") {
const normalized = raw.replace(/\/+$/, "");
if (!normalized) {
throw new Error("NEXT_PUBLIC_API_URL is invalid.");
}
return normalized;
}
const normalized = raw.replace(/\/+$/, "");
if (!normalized) {
throw new Error("NEXT_PUBLIC_API_URL is invalid.");
if (typeof window !== "undefined") {
const protocol = window.location.protocol === "https:" ? "https" : "http";
const host = window.location.hostname;
if (host) {
return `${protocol}://${host}:8000`;
}
}
return normalized;
throw new Error(
"NEXT_PUBLIC_API_URL is not set and cannot be auto-resolved outside the browser.",
);
}