diff --git a/.changeset/cool-buckets-remember.md b/.changeset/cool-buckets-remember.md new file mode 100644 index 0000000000..6f62e66d49 --- /dev/null +++ b/.changeset/cool-buckets-remember.md @@ -0,0 +1,5 @@ +--- +"@medusajs/js-sdk": patch +--- + +fix: Add support for relative base URL to js-sdk diff --git a/packages/core/js-sdk/src/__tests__/client.spec.ts b/packages/core/js-sdk/src/__tests__/client.spec.ts index 3a619a9fbb..58199a56b1 100644 --- a/packages/core/js-sdk/src/__tests__/client.spec.ts +++ b/packages/core/js-sdk/src/__tests__/client.spec.ts @@ -94,6 +94,11 @@ const server = setupServer( statusText: "Internal Server Error", }) }), + http.get(`https://test.com/baseUrl`, ({ request, params, cookies }) => { + return HttpResponse.json({ + test: "test", + }) + }), http.all("*", ({ request, params, cookies }) => { return new HttpResponse(null, { status: 404, @@ -114,7 +119,7 @@ describe("Client", () => { afterEach(() => server.resetHandlers()) afterAll(() => server.close()) - describe("header configuration", () => { + describe("configuration", () => { it("should allow passing custom request headers while the defaults are preserved", async () => { const resp = await client.fetch("header", { headers: { "X-custom-header": "test" }, @@ -162,6 +167,23 @@ describe("Client", () => { const resp = await pubClient.fetch("pubkey") expect(resp).toEqual({ test: "test" }) }) + + it("should gracefully handle a root base URL", async () => { + global.window = { + location: { + origin: "https://test.com", + }, + } as any + + const pubClient = new Client({ + baseUrl: "/", + }) + + const resp = await pubClient.fetch("baseUrl") + expect(resp).toEqual({ test: "test" }) + + global.window = undefined as any + }) }) describe("GET requests", () => { diff --git a/packages/core/js-sdk/src/client.ts b/packages/core/js-sdk/src/client.ts index 03b8ca558b..1bad3d3ce0 100644 --- a/packages/core/js-sdk/src/client.ts +++ b/packages/core/js-sdk/src/client.ts @@ -11,6 +11,20 @@ import { export const PUBLISHABLE_KEY_HEADER = "x-publishable-api-key" +// We want to explicitly retrieve the base URL instead of relying on relative paths that differ in behavior between browsers. +const getBaseUrl = (passedBaseUrl: string) => { + if (typeof window === "undefined") { + return passedBaseUrl + } + + // If the passed base URL is empty or "/", we use the current origin from the browser. + if (passedBaseUrl === "" || passedBaseUrl === "/") { + return window.location.origin + } + + return passedBaseUrl +} + const hasStorage = (storage: "localStorage" | "sessionStorage") => { if (typeof window !== "undefined") { return storage in window @@ -90,7 +104,7 @@ export class Client { private token = "" constructor(config: Config) { - this.config = config + this.config = { ...config, baseUrl: getBaseUrl(config.baseUrl) } const logger = config.logger || { error: console.error, warn: console.warn,