medusajs / nextjs-starter-medusa

A performant frontend ecommerce starter template with Next.js 14 and Medusa.
https://next.medusajs.com/
MIT License
1.78k stars 497 forks source link

Base URL Path Gets Overwritten When Constructing API Request URLs in Medusa Next.js Storefront #405

Open jane-dot-flowers opened 1 week ago

jane-dot-flowers commented 1 week ago

I'm encountering an issue where the path specified in the NEXT_PUBLIC_MEDUSA_BACKEND_URL environment variable is being overwritten when constructing API request URLs. This leads to requests being sent to incorrect endpoints, resulting in errors.

I have set up the NEXT_PUBLIC_MEDUSA_BACKEND_URL to point to a backend URL that includes a custom path:

https://api.example.com/custom-path

However, when the storefront makes API requests, the custom path (/custom-path) gets dropped, and the requests are sent to:

https://api.example.com/store/regions

instead of the expected:

https://api.example.com/custom-path/store/regions

This results in 404 Not Found errors or unexpected HTML responses.


Steps to Reproduce

  1. Set NEXT_PUBLIC_MEDUSA_BACKEND_URL to a URL that includes a custom path:

    NEXT_PUBLIC_MEDUSA_BACKEND_URL=https://api.example.com/custom-path
  2. Start the Medusa backend server and ensure it's accessible at the specified URL with the custom path.

  3. Run the Medusa Next.js storefront.

  4. Access the storefront in the browser.

  5. Observe the network requests being made to the backend.


Expected Behavior

API requests should preserve the custom path specified in the NEXT_PUBLIC_MEDUSA_BACKEND_URL environment variable. For example, requests to fetch regions should be sent to:

https://api.example.com/custom-path/store/regions

Actual Behavior

The custom path is omitted, and requests are sent directly to the domain, resulting in incorrect URLs:

https://api.example.com/store/regions

Analysis

The issue appears to be caused by the way URLs are constructed in the storefront code. When using template literals or the URL constructor with paths that start with a leading slash (/), the existing path in the base URL gets overwritten.

For example, in the middleware or API client:

const response = await fetch(`${BACKEND_URL}/store/regions`, { /* options */ });

If BACKEND_URL includes a path, appending /store/regions results in the base path being discarded.


Proposed Solution

Modify the URL construction logic to correctly handle base URLs that include paths. Here's an example of how this can be achieved:

function constructMedusaUrl(path) {
  const baseUrl = process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL;
  const url = new URL(baseUrl);

  // Ensure no trailing slash on base URL pathname
  const basePath = url.pathname.replace(/\/$/, '');

  // Ensure no leading slash on path
  const relativePath = path.replace(/^\//, '');

  // Construct full path
  url.pathname = `${basePath}/${relativePath}`;

  return url.toString();
}

// Usage
const regionsUrl = constructMedusaUrl('store/regions');
const response = await fetch(regionsUrl, { /* options */ });

Alternative Considerations


Additional Information


Request

Could you please advise on whether base URLs with custom paths are supported in the Medusa Next.js storefront? If so, implementing the proposed solution or providing guidance on the correct way to handle this scenario would be greatly appreciated.

Thank you for your time and assistance.