Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Anchor links from articles not working in Elements Dev Portal #2595

Open
dylangarrett opened this issue Jun 11, 2024 · 0 comments
Open

Anchor links from articles not working in Elements Dev Portal #2595

dylangarrett opened this issue Jun 11, 2024 · 0 comments
Labels

Comments

@dylangarrett
Copy link

The anchor links from any articles written in the Stoplight platform do not work correctly in Angular. The basePath value from the elements component is not considered in the anchor link.

Similar to #1699 and #2133

Context

  • Consider docs hosted at example.com/docs and an article at example.com/docs/article
  • Any anchor links in the article will point at example.com/#anchor instead of example.com/docs/article#anchor
  • Not only is the link incorrect, it might navigate users away from the documentation

Current Behavior

  • Anchor link is incorrect
  • Article anchor links do not consider the basePath of the component
    <elements-stoplight-project
    projectId="..."
    basePath="/api/docs" // this is not reflected in anchor links 
   ></elements-stoplight-project>

Expected Behavior

  • Anchor link should be correct
  • Clicking should scroll to the correct section instead of navigating to a different page

Possible Workaround/Solution

As a workaround I directly modify anchor tags in my component, it works but shouldn't be necessary

export class ApiPortalComponent implements AfterViewInit {
  private mutationObserver: MutationObserver;
  public basePath = '/docs/api';
  private elementsQuerySelector = 'elements-stoplight-project';
  
  constructor(private router: Router, private renderer: Renderer2, private el: ElementRef) {}

  ngAfterViewInit() {
    this.updateAnchorLinks();

    this.mutationObserver = new MutationObserver(() => {
      this.updateAnchorLinks();
    });

    const targetNode = this.el.nativeElement.querySelector(this.elementsQuerySelector);
    if (targetNode) {
      this.mutationObserver.observe(targetNode, {
        childList: true,
        subtree: true,
      });
    }
  }

  ngOnDestroy() {
    if (this.mutationObserver) {
      this.mutationObserver.disconnect();
    }
  }

  /**
   * Fixes an issue where anchor links are not working as expected in Stoplight Elements Dev Portal
   * https://github.com/stoplightio/elements/issues/1699
   * https://github.com/stoplightio/elements/issues/2133
   * 
   * The anchor links do not contain the base path of the API portal, so we need to update them.
   * Loop through all anchor links in the API portal and update the href attribute to include the base path.
   * Also fixes the issue where the page refreshes when clicking on an anchor link.
   */
  public updateAnchorLinks() {
    const anchorLinks = this.el.nativeElement.querySelectorAll(`${this.elementsQuerySelector} a[href^="#"]`);
    anchorLinks.forEach((link: HTMLAnchorElement) => {
      const anchor = link.getAttribute('href')?.split('#')[1];
      if (anchor && link.href.indexOf(this.basePath) === -1) { 

        this.renderer.setAttribute(link, 'href', `${this.basePath}#${anchor}`);
        
        // Add click event listener to prevent full page refresh and scroll to the anchor
        this.renderer.listen(link, 'click', (event) => {
          event.preventDefault();
          void this.router.navigate([this.basePath], { fragment: anchor }).then(() => {
            this.scrollToAnchor(anchor);
          });
        });
      }
    });
  }

  private scrollToAnchor(anchor: string) {
    const element = document.getElementById(anchor);
    if (element) {
      element.scrollIntoView({ behavior: 'smooth' });
    }
  }
}

Steps to Reproduce

  1. Run elements dev portal locally, ensure there is a basePath specified in the component
  2. Write an article which includes headings
  3. Navigate to the article in the dev portal, click a link on the right side
image

Environment

  • Version used: "@stoplight/elements-dev-portal": "2.2.0"
  • Environment name and version (e.g. Chrome 39, node.js 5.4): Chrome
  • Operating System and version (desktop or mobile): Both
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants