elements icon indicating copy to clipboard operation
elements copied to clipboard

Heading anchors do not link properly when router=hash and <base> tag is different from baseUrl

Open sgerace opened this issue 8 months ago • 1 comments

Context

We are embedding Stoplight into a larger documentation site and using the router=hash option to control routing (since the larger documentation site has its own routing engine). We also need to explicitly set the <base> URL element on the site due to specifics in the hosting infrastructure we are using (in our case we are setting <base href="/">). To compensate for this, we are setting the basePath configuration option when we instantiate our Stoplight instance to something like basePath="/docs/api".

Current Behavior

The main navigation links work properly, and are set to full absolute URLs:

Image

However, the heading anchors use a relative path in their href attribute, and thus, with the <base> tag (if it differs from the basePath provided to Stoplight) is not applied:

Image

Expected Behavior

If the baseUrl is provided to Stoplight, it should be included in relative URLs.

Possible Workaround/Solution

A workaround that we've been using is to listen to click events on a elements and modify the href attribute (at time of click) if the href attribute starts with # (indicating it is a relative hash change):

if (this.options.baseUrl) {
  this.stoplight.addEventListener('click', (ev) => {
    const a = ev.target.closest('a');
    if (a && a.href) {
      const href = a.getAttribute('href');
      if (href.startsWith('#')) {
        a.setAttribute('href', this.options.baseUrl + href);
      }
    }
  });
}

Steps to Reproduce

I understand that this isn't quite an exact reproduction of the bug, but I'm quite confident that the following demonstrates the issue (thanks to @danmichaelo for posting a similar issue in #2176)

  1. Load https://danmichaelo.github.io/stoplight-routing-test
  2. Add a <base href="/"> tag to the <head> element of the page
  3. Open the main navigation link and observe how these links are correct (since they are absolute).
  4. Hover over a heading and notice that the link is relative and is now incorrect relative to the base. This is true whether or not a baseUrl attribute is added to the Stoplight element (including if the element is created with baseUrl).

sgerace avatar May 12 '25 21:05 sgerace

The same behaviour occurs for the default router=history option. I tried it with version 9.0.4 and 9.0.6. In both versions, the baseUrl option is ignored and the links are relative. We downgraded to 8.5.2, which is working well.

janslovacek avatar Aug 11 '25 11:08 janslovacek